- Add realtime event-based communication between client and server in a MEAN Stack app
-
Intro to Socket.IO
-
Setting up Socket.IO
-
Our new feature: Hippo Chat
-
Code the UI
-
Frontend Realtime Code
-
Backend Realtime Code
-
The HTTP protocol does not enable bidirectional realtime communication.
-
Fortunately, HTML5 included a new protocol that does - websockets.
-
Socket.IO is a JavaScript library that makes realtime bidirectional event-based communication easier than working with websockets directly.
-
It even works in older browsers without websockets by simulating it using old dinosaur techniques.
- Clients can send a message to the server which in turn can push messages to all clients "listening" on the same channel.
-
Install the Socket.IO Module
? npm install socket.io --save -
We're going to keep our Socket.IO code in a separate file. Create a file named io.js in our project's root folder.
-
Socket.IO needs to mount to the
httpserver, not the Express server. We will require our new io.js module in the /bin/www file:var server = http.createServer(app); // insert new code below the above line var io = require('../io'); io.attach(server);
-
With our io.js now loaded, let's put some test code in it:
var io = require('socket.io')(); io.on('connection', function (socket) { console.log('socket.io connected'); }); module.exports = io;
-
Time to move on to the client...
-
In our index.ejs file, we will need to include a special script file that is generated by the socket.io module on the server:
<!-- existing HTML above --> <script src="/socket.io/socket.io.js"></script> <script> var socket = io(); console.log(socket); </script> </body>
-
The socket.io.js script exposes an
ioglobal function that we executed to obtain our connection to the server which we then assigned to a variable namedsocket. -
Browse to
localhost:3000and check that the Socket object logged in the console has aconnected: trueproperty.
-
We want to add a realtime Chat feature that allows all users connected to the same server to chat with each other.
-
We will need to add some new UI below the Add a Hippo section in the index.ejs file:
- A
<hr>tag for a little visual separation. - Two
<input>elements, one for the message, the other for the user's name. - A Button to send the message.
- A
<div>that will hold a Bootstrap styled List Group. Each List Item will be a message.
- A
-
This Gist contains the HTML to add to index.ejs.
-
Review the HTML.
-
Note the use of a
ng-repeatto stamp out a Bootstrap styled template for each message in themessagesarray. -
We will add the
messagesarray and other code in our AngularJS controller next...
-
What do we need the code to do in our Angular controller?
-
Pseudocode it.
-
We need code to display messages:
- Initialize the
messagesarray to an empty array. - "Listen" for new messages originating from other browsers.
- When a new message is received, put it in the beginning of the of the array so that recent messages display first in the
ng-repeat.
- Initialize the
-
We need code to send a message when the Send Message button is clicked:
- Push our message to the server and include a JS object with two properties - what are they?
- Clear the new message
<textarea>.
Add this code to the HomeController
$scope.messages = [];
// listen for a 'new message' event of the socket object
socket.on('new message', function(msg) {
$scope.$apply(function () {
$scope.messages.unshift(msg);
});
});
// push a new message to the server
$scope.sendMsg = function() {
socket.emit('new message', {user: $scope.username, message: $scope.newMsg});
$scope.newMsg = '';
};This is all the code that needs to be in the io.js file:
var io = require('socket.io')();
io.on('connection', function (socket) {
socket.on('new message', function(msg) {
io.emit('new message', msg);
});
});
module.exports = io;-
Socket.IO (
io) on the server sends a message to all connected clients, including the sending client, using theemit()method. -
The
ioobject is the server, and thesocketwould represent a particular client (browser). -
We have only scratched the surface of Socket.IO's capabilities. It has the concept of namespacing and rooms for more granular control of messages.
-
If you are interested in learning more, be sure to check the docs!
- Disable the Send Message button if there is:
- No name entered for the user
- An empty message
-
Currently, if we refresh our browser, we lose our chat history.
-
Use Mongoose & MongoDB to persist recent chat messages.
- Limit the amount of chat messages persisted to a maximum of 20 messages.
