Book Image

Socket.IO Cookbook

By : Tyson Cadenhead
Book Image

Socket.IO Cookbook

By: Tyson Cadenhead

Overview of this book

Socket.IO is a JavaScript library that provides you with the ability to implement real-time analytics, binary streaming, instant messaging, and document collaboration. It has two parts: a client-side library that runs in the browser, and a server-side library for node.js. Socket.IO is event-driven and primarily uses the WebSocket protocol that allows us to emit data bi-directionally from the server and the client. Socket.IO This book is a complete resource, covering topics from webSocket security to scaling the server-side of a Socket.IO application and everything in between. This book will provide real-world examples of how secure bi-directional, full-duplex connections that can be created using Socket.IO for different environments. It will also explain how the connection vulnerabilities can be resolved for large numbers of users and huge amounts of data/messages. By the end of the book, you will be a competent Socket.IO developer. With the help of the examples and real-world solutions,you will learn to create fast, scalable, and dynamic real-time apps by creating efficient messaging systems between the server side and the client side using Socket.IO.
Table of Contents (15 chapters)
Socket.IO Cookbook
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Using Socket.IO as a cross-browser WebSocket


The native WebSocket implementation in browsers is much less robust than what Socket.IO offers. Sending a WebSocket message from the client only requires the data as a single argument. This means that you have to format your WebSocket data in such a way that you can easily determine what it is for.

If you want to emulate the ease of sending a message without a topic, you can use the socket.send() method to send messages as needed.

The benefits of using the Socket.IO syntax for this type of interaction over plain WebSockets are numerous. They include the built-in fallbacks for browsers that don't support WebSockets. The benefits also include a single unified syntax that is easier to read and maintain.

Getting ready

To get started with Socket.IO as a cross-browser WebSocket, you will need to have Node, Express, and Socket.IO installed. If you have not installed them yet, refer to the previous recipe: Creating an Express server with Socket.IO.

How to do it…

Follow these instructions to use Socket.IO as a cross-browser WebSocket:

  1. First, you'll need to set up your server-side server.js file as follows:

    var io = require('socket.io')(5000),
        sockets = [];
    
    io.on('connection', function (socket) {
        sockets.push(socket);
        socket.on('message', function (message) {
            for (var i = 0; i < sockets.length; i++) {
                sockets[i].send(message);
            }
        });
        socket.on('disconnect', function () {
            console.log('The socket disconnected');
        });
    });
  2. Next, you'll have to create a client-side index.html file with the following code:

    <!doctype html>
    <html>
    <head></head>
    <body>
    <form id="my-form">
    <textarea id="message" placeholder="Message"></textarea>
    <p>
    <button type="submit">Send</button>
    </p>
    </form>
    
    <div id="messages"></div>
    
    <script src="http://localhost:5000/socket.io/socket.io.js"></script>
    <script>
            var socket = io('http://localhost:5000');
            socket.on('connect', function () {
    
                document
                    .getElementById('my-form')
                    .addEventListener('submit', function (e) {
                       e.preventDefault();
                       socket.send(document.getElementById('message').value);
                    });
    
                socket.on('message', function (message) {
                    var messageNode = document.createTextNode(message),
                        messageElement = document.createElement('p');
    
                    messageElement.appendChild(messageNode);
    
                    document.getElementById('messages').appendChild(messageElement);
                });
            });
    </script>
    </body>
    </html>
  3. In our example, we have a simple form that allows the user to post a message that will be sent to all the connected sockets.

  4. If you start your server with node server and open your index.html file by navigating to http://5000/index.html in your browser, you should see the form on the index page:

  5. If you post a message to the form, it should send it to the server, and the server should broadcast it to all the available clients, as shown in the following screenshot:

How it works…

The socket.send(...) method is a shortcut for socket.emit('message', ...). We will take a look at this topic in Chapter 3, Having Two-Way Conversations. This is the reason when the server listens for a message topic, it gets called when the client calls socket.send().

Our server stores an array of all the topics that connect to it. We will loop through all the connected sockets to send the message when it comes. We will also explore better ways to manage the connected sockets in the next chapter.

The client side aids the duty of sending the data from the form to the server. It also listens for new messages from the server to add to the list of available messages in our UI underneath the form.

There's more…

We will keep an array of all the connected sockets so that we will be able to easily send data to all of them as needed. However, keeping an array of all the connected sockets can be a little more tedious than just pushing the sockets to the array when they connect. For example, if a user leaves the page, the socket will disconnect, but it will still be included in the static array.

Fortunately, we will be able to tap into the socket disconnect event by calling socket.on('disconnect'). Using this method, we can remove the socket from our array and avoid sending messages to an abandoned socket connection.

Here is an example of how the disconnect event can be used to manage dropped connections:

var io = require('socket.io')(5000),
    sockets = [];

io.on('connection', function (socket) {
    sockets.push(socket);
    socket.on('disconnect', function () {
        for (var i = 0; i < sockets.length; i++) {
            if (sockets[i].id === socket.id) {
                sockets .splice(i, 1);
            }
        }
        console.log('The socket disconnected. There are ' + sockets.length + ' connected sockets');});
});

See also

  • The Handling connection timeouts section in Chapter 2, Creating Real-Time Dashboards

  • The Creating a simple chat room section in Chapter 3, H aving Two-Way Conversations.