Difference between revisions of "Socket.IO"
(26 intermediate revisions by 4 users not shown) | |||
Line 7: | Line 7: | ||
Before you install Socket.IO, you need to install [[Node.JS]] and NPM, which is often installed automatically when you install Node.JS. | 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: | |
<source lang="bash"> | <source lang="bash"> | ||
− | $ | + | $ npm install socket.io --save |
</source> | </source> | ||
− | '''Note:''' | + | '''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. |
== Messaging == | == Messaging == | ||
Line 39: | Line 39: | ||
=== The Chat Server === | === The Chat Server === | ||
− | You can make a file called chat.js with the following code: | + | You can make a file called ''chat-server.js'' with the following code: |
<source lang="javascript"> | <source lang="javascript"> | ||
// Require the packages we will use: | // Require the packages we will use: | ||
− | + | const http = require("http"), | |
− | + | fs = require("fs"); | |
− | |||
− | // Listen for HTTP connections: | + | 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 |
− | io.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 | ||
+ | }); | ||
}); | }); | ||
+ | |||
</source> | </source> | ||
− | The above code makes a simple HTTP server that responds to all connections with the contents of the file " | + | 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 === | === The Chat Client === | ||
− | Here is a front-end client that could work with our server, in | + | Here is a front-end client that could work with our server, in ''client.html'': |
<source lang="html4strict"> | <source lang="html4strict"> | ||
+ | |||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html> | <html> | ||
− | <head> | + | <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> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | </ | ||
− | </ | ||
− | |||
− | |||
− | </ | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</source> | </source> | ||
− | ''Note:'' This example passes strings as the event data, but you can pass any JavaScript datatype, including object literals. | + | '''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: | To see this in action, save these two files in the same directory, cd over to the directory, and start the server: | ||
− | <source lang="bash">$ node chat.js</source> | + | <source lang="bash">$ node chat-server.js</source> |
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! | 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! | ||
Line 128: | Line 129: | ||
== Resources == | == Resources == | ||
− | The [http://socket.io/ 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. | + | The [http://socket.io/ 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 [https://socket.io/docs/v4/rooms/ here]. |
[[Category:Module 7]] | [[Category:Module 7]] |
Latest revision as of 20:38, 6 June 2024
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!
Contents
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.
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.