Php day2013 sports_statistics


Published on

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Php day2013 sports_statistics

  2. 2. #42 TOBIAS JOSEFSSONChief Technology Officer”Bobbe” / ”Bobby”@TobiasJosefsson#8 EMANUEL WINBLADSoware Engineer”Manne” / ”Manny”@ManneWSPORTS EDITING SWEDENA MEDIA HOUSE FOCUSED ON SPORTS
  3. 3. Overview: Data flow from Operators to Clients
  4. 4. Overview: Data flow from Operators to Clients
  5. 5. Why this complex setup?”Independent” decoupled parts- Easier to test- Easier to maintain / replace- Each part only does one thingMultiple languages- There is no silver bullet
  6. 6. Messaging: ZeroMQ"ZeroMQ is a messaging library, which allows youto design a complex communication systemwithout much effort."– Nicholas Piël”Messaging makes everything possible!”– Alvaro Videla, JSDay 2013 (yesterday)
  7. 7. Messaging: ZeroMQRabbitMQ ZeroMQBroker BrokerlessMessagingSystemMessagingLibraryWhy:- Lightweight- Minimalistic- Small feature set needed
  8. 8. Messaging: ZeroMQCore pattern used:
  9. 9. Overview: Statistics input
  10. 10. Statistics input: External systemSeven Operators per arena, logging events.- Shots on net, shots wide, shots blocked- Goals and assists- Players currently on the ice, shifts- Penalties- Hits- ...and much more...Data is transferred using XML files and http(s).
  11. 11. Overview: Parser
  12. 12. Parser: PHP, mongoDBPHP: Familiar, XML processingDoctrine ODM to share documentswith CMS system (Symfony2).MongoDB: Different attributes/fieldsdepending on event type.Shot Goal PenaltyPlayer Player PlayerGoal section Goal sectionAssistsPOP, NEP (players onice)Penalty reason
  13. 13. Parser: PHP, mongoDBPossible improvements (when needed):Scale - one parser process per game(only changes in this component)Alternatives (PHP based):- Symfony2 (full-stack)- Silex (micro)…
  14. 14. Overview: Editorial input
  15. 15. Editorial input: Symfony2, MySQLMultiple Operators located in different places- Live text comments describing the events- Data tagged with games and teams for filtering- Flexible, adjustable, custom made functionality- CMS also includes REST-ish API used by clients
  16. 16. Overview: Queue Controller
  17. 17. Queue Controller: PHPDecides what messages that should go where.Isn’t this a broker!?Yes, kind of…- Decides which queue(s) to send to.- No information about actual end points.How?
  18. 18. Queue Controller: PHP// Prepare our context and socket$context = new ZMQContext(); // Subscribe to messages from parser$parser = $context->getSocket(ZMQ::SOCKET_SUB); // Connect to publishing socket$parser->connect(tcp://;// Define the channel(s) for// delivery servers to subscribe to$channel = $context->getSocket(ZMQ::SOCKET_PUB); // Bind each channel to an IP and port$channel->bind(tcp://;
  19. 19. Queue Controller: PHP// All in an infinite loop// ...// Receive messages from the parser$msg = $parser->recv(); // Which channels will the message go to$recievingChannels = getChannelsForMsg($msg); // Send message to appropriate channelsforeach ($recievingChannels as $channel) {    $channel->send($msg);}
  20. 20. Overview: Delivery
  21. 21. Delivery: Node.js, SockJSWhy Node.JS?- High concurrency- Same language as clientWhy SockJS?- Lightweight, but still fallbacks for Web Sockets- Option to get ”raw” socketsAlternatives:- (or simply polling...)
  22. 22. NodeJS server codevar server = sockjs.createServer();    server.on(‘connection’, function(conn) {    conn.on(‘data’, function(msg) {        // Check the action passed        switch (msg.action) {         // ...         // Do the corresponding thing...         // I.e. let the client join a channel         // ...        }    });});
  23. 23. // Game event message received from Queue Controllervar gameEventMessage = ”blablabla”; // Send a message to a clientvar conn = getNextClient(clients); conn.write(gameEventMessage);NodeJS server code (cont.)
  24. 24. Delivery: Node.js, SockJSSockJS client codevar sockjs = new SockJS(;sockjs.onopen = function() {    // SockJS connection opened}; sockjs.onmessage = function(e) {    // Message recieved    var msg = JSON.parse(;}; sockjs.onclose = function() {  // Connection closed  // Offer the user possibility to reconnect    $(button#reconnect).show();};
  25. 25. Overview: Monitoring and Logging
  26. 26. Overview: Monitoring and Logging
  27. 27. Overview: Clients
  28. 28. Several versions- Web- Mobile version- Mobile version for arenas (using local WiFi)The different versions share a lot of functionality.Clients: Symfony2, HTML5, JavaScript
  29. 29. Clients: Desktop version
  30. 30. Clients: Mobile versions
  31. 31. What have we learned?- Good to keep things separated- Don’t over engineer the solution! keeping things separated you can re-engineer later –when needed!- Use the tools you know how to handle- Select the most appropriate tool from your own toolchain
  32. 32. SoftwareZeroMQ: http://www.zeromq.orgNodeJS: http://nodejs.orgSockJS: http://www.hockeyligan.seMobile: http://m.hockeyligan.seREFERENCES AND RESOURCES