Socket.IO

From CSE330 Wiki
Jump to navigationJump to search

AJAX is useful when one-way communication is satisfactory for your web application. However, what happens when you need two-way communication, like a chat client or multiplayer game? AJAX isn't the tool for the job. This is where Socket.IO comes in.

Built to work natively with Node.JS, Socket.IO enables asynchronous, two-way communication between the server and the client. This means that the server can send messages to the client without the client having to ask first, as is the case with AJAX. As you learn Socket.IO, Non-Blocking I/O will become your best friend!

Installing Socket.IO

Before you install Socket.IO, you need to install Node.JS and NPM, which is often installed automatically when you install Node.JS.

The NPM package manager is different from many of the package managers we've used in that you need to install remote packages for every project in which you use them. This means that you need to cd to the working directory in which you want to keep your Node.JS JavaScript file, and then run the following command:

$ npm install socket.io --save

Note: If you pass the -g to npm install, then the package will be installed "globally" on your instance, so all Node.JS projects will be able to use it. However, this is not recommended for all projects. Read Node.JS's justification here.

Messaging

Socket.IO works by having clients send messages to the server and the server send messages to clients. For example, consider the code:

// Computer A:
socket.emit("info", {
	"hello": "world"
});

// Computer B:
socket.on("info", function (data) {
	console.log(data.hello);
});

Computer A could be either the client or the server, and Computer B would be the other. When socket.emit(name, data) is called on either end, the callback function in socket.on that listens for the message named name is called with the data from socket.emit.

A First Socket.IO Application: Chat Server and Client

Building a chat client is surprising simple using Socket.IO and Node.JS, and it gives great insight into the workings of Socket.IO. Take the time to understand how this example works, and ask questions; if you understand this, the group portion will be easy!

The Chat Server

You can make a file called chat-server.js with the following code:

// Require the packages we will use:
const http = require("http"),
    fs = require("fs");

const port = 3456;
const file = "client.html";
// Listen for HTTP connections.  This is essentially a miniature static file server that only serves our one file, client.html, on port 3456:
const server = http.createServer(function (req, res) {
    // This callback runs when a new connection is made to our HTTP server.

    fs.readFile(file, function (err, data) {
        // This callback runs when the client.html file has been read from the filesystem.

        if (err) return res.writeHead(500);
        res.writeHead(200);
        res.end(data);
    });
});
server.listen(port);

// Import Socket.IO and pass our HTTP server object to it.
const socketio = require("socket.io")(http, {
    wsEngine: 'ws'
});

// Attach our Socket.IO server to our HTTP server to listen
const io = socketio.listen(server);
io.sockets.on("connection", function (socket) {
    // This callback runs when a new Socket.IO connection is established.

    socket.on('message_to_server', function (data) {
        // This callback runs when the server receives a new message from the client.

        console.log("message: " + data["message"]); // log it to the Node.JS output
        io.sockets.emit("message_to_client", { message: data["message"] }) // broadcast the message to other users
    });
});

The above code makes a simple HTTP server that responds to all connections with the contents of the file "client.html", which we will make in the next step. We tell Socket.IO to listen for "message" events, and when it hears one, it should emit a new event called "someone said" back to the connected clients.

The Chat Client

Here is a front-end client that could work with our server, in client.html:

<!DOCTYPE html>
<html>
   <head>
      <script src="/socket.io/socket.io.js"></script>
      <script>

      var socketio = io.connect();
      socketio.on("message_to_client",function(data) {
         //Append an HR thematic break and the escaped HTML of the new message
         document.getElementById("chatlog").appendChild(document.createElement("hr"));
         document.getElementById("chatlog").appendChild(document.createTextNode(data['message']));
      });

      function sendMessage(){
         var msg = document.getElementById("message_input").value;
         socketio.emit("message_to_server", {message:msg});
      }

      </script>
   </head>
   <body>
      <input type=text" id="message_input"/>
      <button onclick="sendMessage()">send</button>
      <div id="chatlog"></div>
   </body>
</html>

Note: This example passes strings as the event data, but you can pass any JavaScript datatype, including object literals.

To see this in action, save these two files in the same directory, cd over to the directory, and start the server:

$ node chat-server.js

Fire up your favorite browser and navigate to http://localhost:3456/. Open the page in two windows. Violà: you have your (very basic) chat client!

Resources

The Socket.IO web site has concise examples that tell you pretty much all you need to know in order to build a functional Socket.IO web application. A helpful discussion on how to use rooms with Socket.IO can be found here.