Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

WebSockets with PHP: Mission impossible

6 501 vues

Publié le

How to make web socket daemons with PHP. Also in this talk we'll look at some similar topics like MQs

Publié dans : Logiciels
  • Identifiez-vous pour voir les commentaires

WebSockets with PHP: Mission impossible

  1. 1. WebSockets with PHP: Mission Impossible
  2. 2. Who am I? ✔ Yoan-Alexander Grigorov ✔ Proud PHP developer ✔ Likes to screw around with OOP
  3. 3. So what is a WebSocket after all?
  4. 4. WebSocket boosts UX ✔ Forget client pulls ✔ Forget long polling ✔ Make your application event based
  5. 5. What google say about WebSockets: ✔ It's easy to build WebSocket server with node.js ✔ It's hard to build WebSocket server with PHP
  6. 6. Research! Research! Research!
  7. 7. Available tools for PHP ✔ Ratchet ✔ … it's only that. Seriously, it's only Ratchet ✔ Ok, there are some other libraries, all of them named PHPWS
  8. 8. Ratchet http://socketo.me
  9. 9. First things first
  10. 10. Install with composer
  11. 11. Setting up a server with Ratchet <?php use RatchetMessageComponentInterface; use RatchetConnectionInterface; class Handler implements MessageComponentInterface { public function onOpen(ConnectionInterface $conn) {} public function onMessage(ConnectionInterface $from, $msg) {} public function onClose(ConnectionInterface $conn) {} public function onError(ConnectionInterface $conn, Exception $e) {} }
  12. 12. Setting up a server with Ratchet <?php use RatchetServerIoServer; use RatchetHttpHttpServer; use RatchetWebSocketWsServer; $handler = new AppHandler(); $server = IoServer::factory( new HttpServer(new WsServer( $handler ) ), 8123); $server->run();
  13. 13. In the browser var ws = new WebSocket('ws://127.0.0.1:8123'); // ... in some event ws.send('Гледай кви ръки, чуек!'); // ... listener for messages: ws.onmessage = function (message) { alert(message); };
  14. 14. Let's make a chat!
  15. 15. What do we need? ✔ Keep all active connection objects ✔ When a connection sends a message, notify all others ✔ On disconnect – remove connection object from the in-memory cache (map)
  16. 16. Connections handling <?php class Handler implements MessageComponentInterface { private $connections = []; public function onOpen(ConnectionInterface $conn) { $this->connections[$conn->resourceId] = $conn; } public function onMessage(ConnectionInterface $from, $msg) { foreach ($this->connections as $receiver) { $receiver->send($msg); } } public function onClose(ConnectionInterface $conn) { unset($this->connections[$conn->resourceId]); } }
  17. 17. That's it!
  18. 18. Keep an eye on: ✔ Run it like a daemon (/etc/init.d/skeleton) ✔ Fatal errors and exceptions – they kill the daemon ✔ ORMs like Doctrine help you a lot
  19. 19. Doctrine uses Identity Map
  20. 20. Identity map gives you wings!
  21. 21. Web Servers and Web Sockets
  22. 22. Don't forget good old Ajax!
  23. 23. But how ajax could send messages to the WebSocket server?
  24. 24. Message Queues
  25. 25. ZeroMQ ✔ Libzmq ✔ Has a PHP extension in PECL ✔ React/ZMQ (PHP wrapper) ✔ "react/zmq": "0.2.*|0.3.*" in Composer
  26. 26. What you need to know ✔ There are ZeroMQ listeners – They use simple TCP ✔ There are ZeroMQ contexts (senders) – They connect to ZeroMQ listeners and send messages
  27. 27. What you need to know ✔ You need ZeroMQ listener in the WebSocket daemon ✔ Ordinary PHP scripts send messages to the listener ✔ Since ZeroMQ is in the WebSocket daemon, it could easily interact with WebSocket connections
  28. 28. Let's add ZeroMQ to our application!
  29. 29. Add callback for ZeroMQ messages <?php class Handler implements MessageComponentInterface { // ... // this is CUSTOM method (not from interface) public function onZMQMessage($message) { } }
  30. 30. Add ZeroMQ listener to the daemon <?php use ... $handler = new AppHandler(); $server = IoServer::factory( new HttpServer(new WsServer( $handler ) ), 8123); // Listen on 127.0.0.1:4444 $context = new ReactZMQContext($server->loop); $pull = $context->getSocket(ZMQ::SOCKET_PULL); $pull->bind("tcp://127.0.0.1:4444"); $pull->on('message', function ($data) use ($handler) { $handler->onZMQMessage($data); }); $server->run();
  31. 31. In your Ajax server script <?php // ... add stuff to the database, other things... // notify using ZeroMQ: $context = new ZMQContext(); $socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'pusher'); $socket->connect("tcp://127.0.0.1:4444"); $socket->send('Глей кви ръки! Туй аз ли съм!?');
  32. 32. Go! Try it yourself!
  33. 33. Working code examples from this talk: https://github.com/sasquatch-mc/ratchet-example (check the branches)
  34. 34. References ✔ http://socketo.me ✔ http://zeromq.org
  35. 35. Thanks and good luck! ✔ joan.grigorov@gmail.com ✔ bgscripts.com

×