【发布时间】:2015-04-08 17:11:23
【问题描述】:
我尝试构建一个小的实时 websocket 用例,用户可以在其中登录并查看所有其他登录的用户,在新用户登录或现有用户注销时收到通知。
对于这种情况,当用户登录或注销时,我在我的 UserController 中使用 ZMQ PUSH Socket。
用户控制器
public function login() {
//... here is the auth code, model call etc...
$aUserData = array();// user data comes from the database with username, logintime, etc....
$context = new \ZMQContext();
$oSocket = $context->getSocket(\ZMQ::SOCKET_PUSH, 'USER_LOGIN_PUSHER'); // use persistent_id
if($oSocket instanceof \ZMQSocket) {
$oSocket->connect("tcp://127.0.0.1:5555"); //
$oSocket->send(json_encode($aUserData));
}
}
public function logout() {
//... here is the logout code, model call etc ....
$aUserData = array();// user data comes from the SESSION with username, logintime, etc....
$context = new \ZMQContext();
$oSocket = $context->getSocket(\ZMQ::SOCKET_PUSH, 'USER_LOGOUT_PUSHER'); // use persistent_id
if($oSocket instanceof \ZMQSocket) {
$oSocket->connect("tcp://127.0.0.1:5555"); //
$oSocket->send(json_encode($aUserData));
}
}
然后我有一个像 Ratchet 文档中一样的 Pusher 类:link
在这个类中,有两种方法:onUserLogin 和 onUserLogout,当然还有其他的东西,比如
onSubscribe、onOpen、onPublish
用户信息推送器
public function onUserLogin($aUserData) {
//var_dump("onUserLogin");
$sUserData = json_decode($aUserData, true);
$oTopic = $this->subscribedTopics["user_login"];
if($oTopic instanceof Topic) {
$oTopic->broadcast($sUserData);
} else {
return;
}
}
public function onUserLogout($aUserData) {
//var_dump("onUserLogout");
$entryData = json_decode($aUserData, true);
$oTopic = $this->subscribedTopics["user_logout"];
if($oTopic instanceof Topic) {
$oTopic->broadcast($entryData);
} else {
return;
}
}
最后一块是 WampServer/WsServer/HttpServer,它有一个 Loop 监听传入的连接。还有我的ZMQ PULL socket
RatchetServerConsole
public function start_server() {
$oPusher = new UserInformationPusher();
$oLoop = \React\EventLoop\Factory::create();
$oZMQContext = new \React\ZMQ\Context($oLoop);
$oPullSocket = $oZMQContext->getSocket(\ZMQ::SOCKET_PULL);
$oPullSocket->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
$oPullSocket->on('message', array($oPusher, 'onUserLogin'));
$oPullSocket->on('message', array($oPusher, 'onUserLogout'));
$oMemcache = new \Memcache();
$oMemcache->connect('127.0.0.1', 11211);
$oMemcacheHandler = new Handler\MemcacheSessionHandler($oMemcache);
$oSession = new SessionProvider(
new \Ratchet\Wamp\WampServer(
$oPusher
),
$oMemcacheHandler
);
//$this->Output->info("Server start initiation with memcache!...");
$webSock = new \React\Socket\Server($oLoop);
$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect
$oServer = new \Ratchet\Server\IoServer(
new \Ratchet\Http\HttpServer(
new \Ratchet\WebSocket\WsServer(
$oSession
)
),
$webSock
);
$this->Output->info("Server started ");
$oLoop->run();
}
在此示例中,来自 login() 或 logout() 的调用将始终调用这两个方法(onUserLogin 和 onUserLogout)。 我找不到一些文档,这些文档描述了我可以在 on($event, callable $listener) 方法中使用哪些事件,有人有链接/知识库吗? 检查 UserController 中哪个方法被触发的最佳方法是什么?
- 我可以在 Controller 中的 $sUserData 中添加一些信息,然后在 Pusher 中进行检查
- 我可以将另一个套接字绑定到不同的端口(例如 5554 用于 PULL 和 PUSH)并在这个端口上使用 on() 方法
- 我可以...是否有其他最佳做法可以解决此问题?
不需要客户端代码,因为它可以正常工作
【问题讨论】:
-
能否请您提及访问“new \ZMQContext();”的步骤?因为我不能这样做。我在这里问过同样的问题stackoverflow.com/questions/41054517/…
标签: php websocket zeromq ratchet reactphp