Node.js Socket.io

Introduction
Node.js is a server side javascript interpreter. Basically you write a program in Javascript for the server and not for the browser.

Socket.io is a library for node.js applications to support real-time event-based communications with the browser.

Coffee and Power specific configuration
We have open ports on both instances:
 * dev.sendlove.us 7200 - 7220 range
 * coffeeandpower.com 7200 - 7220 range

7200 is reserved for currently running server side application so it's not available for development.

Port can be used only by one node.js script at a time so for development you have to change it to available one!

Example of development process
If you want to work with socket.io:
 * Check out current version of candpweb repository
 * In the root of the file you'll find two directories 'web' and 'tools'
 * Server side of socket.io is in 'tools/socket'
 * Client side is in 'js/socket.io' and in other 'js' files that are using it


 * Find out what port is available and use it for development and testing. For this change it in 'tools/socket/socket.js' and run server side script with 'node socket.js'
 * If port is taken you'll see an exception output if it's free - console will output info about starting socket.io and listening for connections


 * In your server.local.php change the port to the same as node.js script is using with define('CANDP_SOCKET_URL', SERVER_NAME . ':7201');
 * Make sure SERVER_NAME is set to 'dev.sendlove.us' not 'coffeeandpower.com' - it's for production.


 * If you are done developing you can run server side in background using 'nohup node tools/socket/socket.js &' so you won't have to have open ssh session while review is going on.
 * After review is done and you are ready to commit your changes:
 * Kill your node.js process you previously started with 'nohup'. Be careful not to kill the production version!
 * If you didn't take a note of PID (which you should) of your script use 'pgrep node | xargs ps' and kill the one you started. Again be careful not to kill production process or process of another dev.


 * Change port back to 7200 in tools/socket/socket.js.
 * After you commit your changes will be deployed to 'dev.sendlove.us' and 'coffeeandpower.com' and both node.js instances will be restarted so you can test your work on production.

Example of script to update user location change in real time for Coffee and Power (overview)
Server side script is a fie in tools/socket/socket.js
 * 1) Server side script:

What it does is create an http server with sockets support (socket.io).

All socket communication is handled by socket.io - if browser support Websockets - it uses them, if not - XHR polling and so on.

Full list of supported transports are on Socket.io site.

socket.io gives has 'connection' event which gives us connected user which has 2 events - 'message' and 'disconnect'.

When new user connects we add him to 'onlineUsers' hash array.

We remove that user on disconnect.

On connection we don't know much about the user - only his unique sessionId, so when we receive message with action 'update' - we look this user up in 'onlineUsers' and update his data.

Right now we store only his map bounds - we are not interested in his location - we only need to know whether he needs an update or not.

Server receives user updates using http request to the server - this way we can update users location from whatever place we want.

We send user is, his new location and his old location.

On receive we filter online users who can see our user changing location - if they can see him - send them an update.

Client side script is /web/js/socket.js
 * 1) Client side script:

I connects to the server on port 7200 - dev.sendlove.us:7200

After we know our map bounds we update the server with that info (introducing ourselves).

Main event here is receiving message from the server.

Here we parse which action to execute on message. If action is 'locationUpdate' - it means one of the dots changed it's location.

Find that dot in hash array of markers and change it position for new one.

CandPSocket object creates event 'onLocChangeNotification' which is used by candp.js to update user location.


 * 1) Example of extending it to create real-time user status updates:

Server side:
 * create event 'onUserStatusChange' wneh server is hit with url like '/statusUpdate'
 * inside 'onUserStatusChange' find users to send message to with filterUsersToBroadcast(user) and send data with action: 'statusUpdate'

Client side:
 * handle 'statusUpdate' in switch statement and execute '_onStatusUpdate' callback created with 'onStatusChangeNotification'
 * 'onStatusChangeNotification' will execute the action for status update in main script

That's that easy. Same goes for missions and other events. Some data can be updated with GET requests (like it's done now) - so it would work for users that are not connected to the socket (makes sense if it's something that is processed by php anyway) and some can be broadcasted directly - for example chat user typing status.