php - 从 PHP 脚本向多个 Ratchet Websocket 应用程序发送消息(通过 ZMQ Socket)

标签 php zeromq ratchet phpwebsocket

所以,我正在运行一个 Ratchet (php) websocket 服务器,它有多个连接多个 Ratchet 应用程序 (MessageComponentInterfaces) 的路由:

//loop 
$loop   = \React\EventLoop\Factory::create();

//websocket app
$app = new Ratchet\App('ws://www.websocketserver.com', 8080, '0.0.0.0', $loop);

/*
 * load routes
 */
$routeOne = '/example/route';
$routeOneApp = new RouteOneApp();
$app->route($routeOne, $routeOneApp, array('*'));

$routeTwo = '/another/route';
$routeTwoApp = new AnotherApp();
$app->route($routeTwo, $routeTwoApp, array('*'));

从这里我绑定(bind)一个 ZMQ 套接字,以便能够接收从在普通 apache 服务器上运行的 php 脚本发送的消息。
// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new \React\ZMQ\Context($loop);
$pull = $context->getSocket(\ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5050'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($routeOneApp, 'onServerMessage'));

最后,服务器启动:
//run
$loop->run();

只要我只将一个 Ratchet 应用程序绑定(bind)到 ZMQ 套接字,这一切都很好。但是,我希望能够分别将消息推送到两个 Ratchet 应用程序。为此,我想将两个 ZMQ 套接字绑定(bind)到不同的路由,例如:
$pullOne->bind('tcp://127.0.0.1:5050' . $routeOne); // Binding to 127.0.0.1 means the only client that can connect is itself
$pullOne->on('message', array($routeOneApp, 'onServerMessage'));


$pullTwo->bind('tcp://127.0.0.1:5050' . $routeTwo); // Binding to 127.0.0.1 means the only client that can connect is itself
$pullTwo->on('message', array($routeTwoApp, 'onServerMessage'));

但是,这会在绑定(bind)第二个套接字时导致来自 ZMQ 的错误消息,指出给定地址已在使用中。

所以问题是,有没有其他方法可以通过 ZMQ 套接字使用路由?
或者我应该使用其他方式来区分单独的 Ratchet 应用程序的消息,如果是这样,什么是一个好的解决方案?
我想过绑定(bind)到 2 个不同的端口,但认为这将是一个非常丑陋的解决方案?!

最佳答案

通常在 TCP 数据包中由 4 个元组标识(发送方 ip、发送方端口、接收方 ip、接收方端口)。

当传入的数据包到达网络层时,通过查看接收方 ip 和端口将其转发到适当的应用程序。如果您对两个应用程序使用相同的配对,则该层将无法决定在连接进入时将其发送给谁。

一种解决方案是绑定(bind)单个连接并编写一个查看传入内容的通用处理程序,然后决定(我假设你有一些逻辑)区分不同实例的传入连接,然后调用相应的处理程序。处理程序可以获取连接对象并可以处理连接。

如果您的两个实例是相同的,并且谁收到请求并不重要,那么您可以将新连接随机转发到任何处理程序。

编辑:无论应用程序类型(Racket/ZMQ 等)如何,我都试图回答这个问题,因为您试图解决的问题是任何网络应用程序共同的基本问题。

对于这种情况,由于您有两个应用程序正在运行并希望在同一个端口上监听,因此您可以拥有一个通用处理程序,它可以查看请求 URL 并将连接转发到适当的处理程序。

可以使用获取请求 URL

$querystring = $conn->WebSocket->request->getQuery();

现在客户端可以使用
ws://localhost:5050/app1 
and
ws://localhost:5050/app2

您的不同应用现在可以分别处理这些连接。

关于php - 从 PHP 脚本向多个 Ratchet Websocket 应用程序发送消息(通过 ZMQ Socket),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42095900/

相关文章:

php - 我可以告诉 Apache 从 PHP 进行内部重定向吗?

python - python 代码没有名为 zmq 的模块

php - 未找到类 'MyApp\Thread'

php - 在 mysql 中存储复选框值

php - 显示一个表的所有结果以及在哪个区有多少

synchronization - 分布式客户端之间同步状态的方式

javascript - Ratchet 删除/添加数据忽略 ="push"

javascript - WebRTC 视频通话和音频通话不起作用,只能聊天吗?

javascript - 宏伟的弹出窗口获得帖子父级的永久链接

python - Django 中的 Zeromq PUSH/PULL