-
Notifications
You must be signed in to change notification settings - Fork 16
Part 2: Building the server with Node.js and Socket.io
In order to have the skeleton of the project, we'll rely on express.js (the sinatra-like framework). Install express globally with the following command:
sudo npm install –g express
Now let's create an express based app called mobos-chat
express mobos-chat
The following structure will be created
create : mobos-chat
create : mobos-chat/package.json
create : mobos-chat/app.js
create : mobos-chat/public
create : mobos-chat/views
create : mobos-chat/views/layout.jade
create : mobos-chat/views/index.jade
create : mobos-chat/public/images
create : mobos-chat/routes
create : mobos-chat/routes/index.js
create : mobos-chat/routes/user.js
create : mobos-chat/public/stylesheets
create : mobos-chat/public/stylesheets/style.css
create : mobos-chat/public/javascripts
Notice that a file called package.json containing the dependencies has been created. Execute npm install to add them to the project (check that the node_modules folder is created and contains the dependencies).
The app.js is the entry point to our application, it imports the required modules, defines some routings and creates the http server. Open and take a look at it. This should be enough to start our application.
Execute node app or npm start to start the app. Check that typing 'http://localhost:3000/' in your browser gives you the welcome page.
By now, you should be familiar with packages.json. In order to add the Socket.io support we need to define it as a dependency in such file, open it and add:
"socket.io" : "~0.9.16". Run npm install again to fetch the dependency.
Let's now create a module which will encapsulate the socket.io logic. Create a file called socket.js inside the routes folder.
This module will use the socket.io dependency that we have already defined. Import it in the module
var socketio = require('socket.io');
The modules contain logic private to the module itself, they encapsulate logic, but remember that they can also expose it using the CommonJS convention (with the exports variable). Let's expose a function called initializeso we can initialize it from another module:
exports.initialize = function(server) {
io = socketio.listen(server);
}
We have added a server parameter (this will be the http server already created in the app.js file) and we are initialized socketio in order to start accepting connections. Now its time to use our module.
Open the app.js and add the module we just created var io = require('./routes/socket.js');. Remember we exposed an initialize function expecting an http server as a parameter. If you scroll at the end of the file, you will see how the http server is created (by default listening at the port 3000). Lets get a reference on that server so we can pass it to the module
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
You can now call the initialize function, passing the server parameter:
io.initialize(server);
Start the app again (node app) and check you see something like info - socket.io started on the console.
Now we have the app already listening for WebSocket connections, but we need to handle the events (new connection, disconnection, messages...). Let's add a connection listener inside the initialize method:
io.sockets.on('connection', function(socket) {
// All your handlers here, socket will be the connected client
});
-
Provide a handler for the event 'user:setname'. This will be triggered by the client right after connecting. (Tip: remember
socket.on('event', function (data) {}?). The message received will be something similar to{'nickname': 'sergi'}. Set the value to the socket session so we can remember the username and we don't force it to be send over and over again (hint: use socket.set). Broadcast a message like '{message:'sergi has joined!'} to all connected users. -
Provide a handler for the event 'user:message'. This event will be triggered when a user sends a message to the chat. The data will be a JSON similar to this:
{'message':'Hey there'}. Broadcast the message to all the other clients adding the nickname to it (hint: usesocket.get(var, function (err, nickname) {})to get the previously stored nickname). The resulting message should be like{'message' : 'Hey there', 'nickname' : 'sergi'}
BONUS:
- Store the user names in an array
var users = [];, store the name when they connect and remove them when they disconnect.