I try to build a little realtime websocket use-case, where users can login and see all other users logged in, get notified when a new user signs in or an existing user logs out.
For this scenario i use the ZMQ PUSH Socket in my UserController when a user logs in or logs out.
UserConstroller
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)); } }
Then i've got a Pusher class like in the Ratchet docs: link
In this class there are two methods: onUserLogin and onUserLogout and of course all the other stuff like
onSubscribe, onOpen, onPublish
UserInformationPusher
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; } }
The last piece is the WampServer/WsServer/HttpServer with a Loop that listens to the incoming connections. There is also my 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(); }
In this example, the call from login() or logout() would always call both methods(onUserLogin and onUserLogout).I was not able to find some docs, which describe what events i can use in the on($event, callable $listener) method, does anyone have a link/knowledge base?What is the best approach to check which method from the UserController was fired?
- I could add some information to the $sUserData in the Controller and check this in the Pusher
- I could bind an other socket to a different port (e.g. 5554 for PULL and PUSH) and use the on() method on this one
- I could... is there another best practice to solve this?
No Client code needed cause it works fine