Я использую https://github.com/orchidsoftware/web-socket в своем проекте laravel и хочу отправлять сообщения подключенным клиентам.
Пока я следил за README и запустил сервер - я получаю предупреждение «Соединение установлено».
Но когда я пытаюсь отправить сообщение клиенту, ничего не происходит. Я создал функцию sendMessageToAll и попытался вызвать ее как из onOpen, так и из другого контроллера:
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
$this->sendMessageToAll("message");
}
public function sendMessageToAll($msg){
foreach ($this->clients as $client) {
$client->send($msg);
}
}
И с другого контроллера:
public function test() {
$ws = new WebSocketClass();
$ws->sendMessageToAll("testing");
}
Что-то мне не хватает для того, чтобы запустить его?






С другого контроллера? Вы не можете получить доступ к процессу (скрипту php), запущенному в другом потоке (это ваш сервер). Socket-сервер - это концентратор между подключенными клиентами, ожидающий сообщения и, если он получил его, отправляет его снова (если было сказано сделать это). Другими словами - если вы хотите отправить сообщение всем подключенным клиентам, вы должны быть одним из них.
Ваш исходный код выглядит нормально, сервер должен быть запущен. Итак, проверьте это.
Самый простой способ - открыть несколько telnet-соединений с вашим сокет-сервером и начать обмен сообщениями.
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
$msg = "Connection established!\n"
echo $msg; // send server log to shell
sendMessageToAll($msg); // your initial function should be working
}
public function onMessage(ConnectionInterface $from, $msg) {
echo "Message from: {$conn->resourceId} received!\n"; //log again
sendMessageToAll($msg);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "Error: {$e->getMessage()}\n";
$conn->close();
}
Также отладьте функцию отправки:
public function sendMessageToAll($msg){
foreach ($this->clients as $client) {
echo "Sending message to {$client->resourceId} \n";
$client->send($msg);
}
}
Теперь откройте несколько соединений telnet с портом сервера сокетов (заметьте в консоли сервера):
telnet 127.0.0.1 8080
и отправьте сообщение от одного из них. Опять же, вы должны получить уведомление от сервера и сообщение от каждого клиента telnet.
Ваш клиент должен быть подключен к вашему серверу сокетов через Javascript, как говорится в документации:
var socket = new WebSocket("ws://localhost");
socket.onopen = function() {
alert("The connection is established.");
};
socket.onclose = function(event) {
if (event.wasClean) {
alert('Connection closed cleanly');
} else {
alert('Broken connections');
}
alert('Key: ' + event.code + ' cause: ' + event.reason);
};
socket.onmessage = function(event) {
alert("The data " + event.data);
};
socket.onerror = function(error) {
alert("Error " + error.message);
};
//To send data using the method socket.send(data).
//For example, the line:
socket.send("Hello");
И вам нужно сначала запустить свой сокет-сервер следующим образом:
Create socket listener:
To create a new listener, you need to
php artisan make:socket MyClass
In the folder app/HTTP/Socket/Listener create template Web listener socket
After creating a need to establish a route which Is located routes/socket.php
//routing is based on an Symfony Routing Component
$socket->route('/myclass', new MyClass, ['*']);
To launch the web-socket, use the command:
php artisan socket:serve
Затем вы следуете авторизации в серверной части, как указано в github.
Да, я сделал это, но как мне отправить сообщение клиенту из серверной части?
Ваши onOpen () и sendMessageToAll () отправят сообщение из бэкэнда клиентам. Другой ваш контроллер не нужен. Клиенты будут подключаться к вашему серверу websocket через JS. Ваш sendMessageToAll отправит сообщение при условии, что к вашему серверу сокетов подключены клиенты.
Если вы еще не читали его, существует закрытый вопрос по этой теме, в котором говорится следующее.
you must send a message using php to the working socket. I use Pawl for such purposes.
Вопрос: Как отправить сообщение со стороны сервера? # 11
Я использую расширение Swoole для операций с сокетами, и у меня никогда не было такой проблемы. Просто попробуйте на своих сервисах; https://www.swoole.co.uk/
Есть ли ошибки? Соединение с вашим сервером все еще открыто и активно?