Всем добра! Не могу понять почему при попытке отправить приватное сообщение соединение рвётся. Гуглил чаты, каналы... ничего с воркермэеном не нашлось. Использую эту либу https://github.com/walkor/Workerman Логи чистые, ошибок нет. Код сервера: PHP: if ($toUserId == 0) { // Отправляем сообщение всем пользователям $messageData['action'] = 'PublicMessage'; foreach ($connections as $c) { $c->send(json_encode($messageData)); } } else { $messageData['action'] = 'PrivateMessage'; if (isset($connections[$toUserId])) { // Отправляем приватное сообщение указанному пользователю $connections[$toUserId]->send(json_encode($messageData)); // и отправителю $connections->send(json_encode($messageData)); } else { $messageData['text'] = 'Не удалось отправить сообщение выбранному пользователю'; $connection->send(json_encode($messageData)); } } Буду благодарен за подсказку/помощь, которая поможет решить проблему. Спасибо!
По этому коду не совсем понятно. Может у вас вообще синтаксическая ошибка. В строке 14 пишете $connections->send(json_encode($messageData));, хотя судя по коду выше $connections это массив объектов, а в строке 18 пишете $connection->send(json_encode($messageData));
Вот начало кода: PHP: $worker->onMessage = function($connection, $message) use (&$connections) { $messageData = json_decode($message, true); Ну и PHP: $connections = []; // сюда будем складывать все подключения
Вы в коде выше пишете PHP: // и отправителю $connections->send(json_encode($messageData)); Откуда у массива $connections метод send?
Код с примера, с гитхаба PHP: // Отправляем сообщение всем пользователям $messageData['action'] = 'PublicMessage'; foreach ($connections as $c) { $c->send(json_encode($messageData)); } PHP: $worker->onMessage = function($connection, $message) use (&$connections) {
В примере с гитхаба объект $connection у которого есть метод send, вы же там где отправляете приватное сообщение, вызываете метод send у массива $connections. А вообще что там за сообщения? Обычный чат? Зачем вы отправляете это же сообщение отправителю.
Да, в этом косяк. Заработало! Спасибо большое! Осталось понять: - как он назначает ID юзерам - можно ли указать свои допустим с БД, что бы создавать чат на двоих только. Типо комнаты. - почему нельзя отправить сообщение когда человек закрыл чат P.S. Куда можно скинуть благодарность?
можно использовать ip пользователя вот например когда подключается PHP: $serverIP = gethostbyname(gethostname()); $ws_worker = new Worker("websocket://{$serverIP}:2346"); $ws_worker->onConnect = function($connection) { echo "Клиент " . $connection->getRemoteIp() . " соединился. Дата " . date("Y-m-d H:i:s") . "\n"; }; $ws_worker->onClose = function($connection) { echo "Клиент " . $connection->getRemoteIp() . " разорвал соединение. Дата " . date("Y-m-d H:i:s") . "\n"; };
1. Я уже не помню, как там внутри все устроено в Workerman. 2. Вам нужно использовать базу данных и делать проверки на права отправлять сообщение. 3. Ну потому что он закрыл чат), некому же отправить. Если вы имеете ввиду, что сообщение пропадает, то вам нужно хранить сообщение в базе.
А когда человек заходит в какую то комнату, заранее созданную кем то в бд: PHP: $ws_worker->onMessage = function($connection, $data) { $get = json_decode( $data, true ); $ip = $connection->getRemoteIp(); if(isset($get['entry_room']) ){ //запись в базу что пользователь $ip вошел в комнату } } ну это как вариант, поидее, он же должен войти в чат под каким то ником, и уже должен быть в базе
@webog там много вариантов, экспериментируйте --- Добавлено --- Смотрите логику. 1.когда кто то подключается к вебсокету, $ws_worker->onConnect смотрите по ip подключался ли он до этого, какой у него ник, в комнате ли он уже. Если да, то отправляете все клиенту, с его ником, комнатой. Там логика JS уже. 2. когда кто то новый авторизуется, входит, регистрируется, входит в новые комнаты. Используйте $ws_worker->onMessage. Делайте какие то манипуляции в бд, и возвращайте ответ пользователю.
@webog Чтобы проверять права, когда пользователь авторизуется, создаете для него уникальный токен и при коннекте и отправке сообщений, посылаете этот токен вместе с запросом на сервер. По поводу id, вы же сейчас сами назначаете им id? Откуда $toUserId? PHP: // Отправляем приватное сообщение указанному пользователю $connections[$toUserId]->send(json_encode($messageData)); --- Добавлено --- Он когда снова авторизуется, вы просто показываете ему сообщения. Вебсокет тут не причем.
С этим не разобрался, криво как-то работает. Вот: PHP: $worker->onMessage = function($connection, $message) use (&$connections) { $messageData = json_decode($message, true); $toUserId = isset($messageData['toUserId']) ? (int) $messageData['toUserId'] : 0;
В общем экспериментируйте, нечего тут уже обсуждать =) --- Добавлено --- @webog Вот тут еще почитай, думаю разберешься https://github.com/walkor/Workerman/issues/175
Непонятно что это за каналы на другом порте. PHP: $channel_server = new Channel\Server('0.0.0.0', 2206);
Вебсокет запускается на одном порту, это на другом. На клиенте делай подключатся через js именно Channel. Я же говорю пробуй)