使用 Web Socket 向客户端发送消息

Posted

技术标签:

【中文标题】使用 Web Socket 向客户端发送消息【英文标题】:Sending message to client with Web Sockets 【发布时间】:2018-10-01 20:17:29 【问题描述】:

我在我的 laravel 项目中使用https://github.com/orchidsoftware/web-socket,我想向连接的客户端发送消息。

到目前为止,我已按照自述文件启动并运行服务器 - 我收到警报“连接已建立。”。

但是当我尝试向客户端发送消息时,没有任何反应。我创建了一个 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");

为了启动并运行它,我是否缺少某些东西?

【问题讨论】:

有错误吗?与您的服务器的连接是否仍然打开并处于活动状态? 【参考方案1】:

来自另一个控制器?您无法访问在另一个线程(即您的服务器)中运行的进程(php 脚本)。套接字服务器是连接客户端之间的集线器,等待消息,如果收到消息,则再次发送(如果被告知这样做)。换句话说 - 如果您想向所有连接的客户端发送消息,您必须成为其中之一。


您的初始代码看起来不错,服务器应该已启动并正在运行。所以,测试一下。

最简单的方法是打开一些到您的套接字服务器的 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);
    

现在,打开一些到您的 socketserver 端口的 telnet 连接(在服务器控制台中被注意到):

telnet 127.0.0.1 8080

并从其中一个发送消息。同样,您应该得到服务器的通知并接收每个 telnet 客户端的消息。

【讨论】:

【参考方案2】:

您的客户端应该通过 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() 将从后端向客户端发送消息。不需要您的另一个控制器。客户端将通过 JS 连接到您的 websocket 服务器。假设有客户端连接到您的套接字服务器,您的 sendMessageToAll 将发送消息。【参考方案3】:

如果您还没有阅读过它,有一个关于此主题的已关闭问题,说明如下。

you must send a message using php to the working socket. I use Pawl for such purposes.

问题:如何从服务器端发送消息? #11

https://github.com/orchidsoftware/web-socket/issues/11

【讨论】:

【参考方案4】:

我正在使用 Swoole 扩展进行套接字操作,但我从来没有遇到过这样的问题。只需在您的服务上试用即可; https://www.swoole.co.uk/

【讨论】:

以上是关于使用 Web Socket 向客户端发送消息的主要内容,如果未能解决你的问题,请参考以下文章

python Socket.IO 客户端,用于向 TornadIO2 服务器发送广播消息

使用 socket.io 向特定客户端发送消息,同时套接字 id 快速变化

向 Socket.io 中的其他房间发送消息

通过 socket.id 向客户端发送消息

Java Socket 未向客户端和服务器发送消息

socket.io 如何跨多个服务器发送消息?