May 15, 2024
Get featured on Geeklore.io
Geeklore is in very early stages of development. If you want to help us grow, consider letting us sponsor you by featuring your tool / platform / company here instead of this text. 😊
If you read my other post you already know what we are going to build. If not - let me explain. We are going to build a version of ChrisOnCode's 'Crazy Buttons' lesson. We are going to create a button which when clicked, moves to a random location within the document. We are also going to make the movement real-time so other people see if there is somebody else clicking it.
As stated by the developers themselves: "Socket.IO is a JavaScript library for realtime web applications. It enables realtime, bi-directional communication between web clients and servers. It has two parts: a client-side library that runs in the browser, and a server-side library for Node.js"
So basically it's a library that allows us to create realtime applications. An example of such is the .io games and the Facebook chat. I suggest you take a look at their official website. Checking this link could also help you understand how it works.
Now you know what we are going to build as well as with what.
As I am using Windows, I will be using Windows terms but if you're using another OS I am sure you will manage. Okay, we will start by setting up the environment. Create a new folder and name it The internet button. Open VS Code in the folder and create the following structure:
Now we need to build the fundamentals of our application. Open a terminal in the directory and type
npm init
Leave the values blank, or add your name and description - it's your choice. We also need to install nodemon so we don't have to restart our application each time we make a change. Do so with
npm install -g nodemon
The last packages we need to install are express & socket.io
npm install --save express socket.io
After all the package installation, your package.json should look similar to this:
Cool, we are ready and set. Let's get to work!
We will start with creating a server.js file inside our server folder. Now let's setup all the variables we need. We will start loading our modules first. Add the following 4 variables:
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
Okay, now let's set-up the express server. We will first set our path to serve our HTML through the public folder we created:
const publicPath = path.join(__dirname, '/../public');
We also need to specify a port our app is going to run on. Let's go with 3000:
const port = process.env.PORT || 3000;
Now we call our express function with:
let app = express();
We then specify the http method to let HTTP connection in:
let server = http.createServer(app);
Lastly, we set up our socketIO connection:
let io = socketIO(server);
Our server.js file should have the following lines of code:
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const publicPath = path.join(__dirname, '/../public');
const port = process.env.PORT || 3000;
let app = express();
let server = http.createServer(app);
let io = socketIO(server);
We need to set our express server to finally serve the content:
app.use(express.static(public path));
And finally connecting to the port:
server.listen(port, ()=> {
console.log(`Server is up on port ${port}.`)
});
Cool, we are all set. Now go inside the public folder, create a simple index.html file and add something to it. I am going to create a blank HTML document and add an h3 tag containing "Welcome to the socket.io training!". Go to your browser and type localhost:3000 to verify everything is working.
Perfect. Let's advance!
As this is a socket.io tutorial I'm not going to fall into details on how to set-up your HTML & CSS. Instead, I'm going to give you a link to the project without the socket.io part and we will build that instead. link
If you clone the project, keep in mind you have to create the folder server and add your server.js file. You also need to add app.js inside the public/js folder.
Okay, we already know what socket.io is and how it works. It is now time to make it work with our buttons. Insite public/js we are going to create an app.js file. We add our socket at the top
let socket = io();
We get our starting section. It contains components, visible before we click the "Start" button and disappear when we start the game.
const startingSection = document.querySelector('.starting-section');
And the 'Start' button...
const homeBtn = document.querySelector('.home-btn');
Finally, our 'crazy' button. The one that moves:
let crazyButton = document.getElementById('crazyButton');
Go to the server/server.js file and open a socket.io connection with the following code:
io.on('connection', (socket) => {
console.log('A user just connected.');
socket.on('disconnect', () => {
console.log('A user has disconnected.');
})
});
This is a built-in function. Whenever a new connection is made, the code within it will be executed. We include another built-in function disconnect which is self-explanatory.
We can test this by starting nodemon (nodemon server/server.js) and browsing to localhost:3000. Open the terminal in VS Code and check if a message is being logged.
Let's create the functionality for the "Start" button. We are going to hide the .starting-section components and also make it real-time so they hide for other players as well. Navigate to app.js and add a click event listener to the start button:
start button.addEventListener('click', () => {
})
Inside our event listener, we must emit a message to the socket.io server with socket.emit('startGame');:
startButton.addEventListener('click', () => {
socket.emit('startGame');
});
Now on the server side(server.js), we must create a 'listener' for that message:
socket.on('startGame', () => {
})
We emit a message back to all the connected clients:
socket.on('startGame', () => {
io.emit('startGame');
})
We then process the 'message' from the server in our app.js:
socket.on('startGame', () => {
});
and we call the function hideStartButton():
socket.on('startGame', () => {
hideStartButton();
});
Finally, we declare our hideStartButton function:
function hideStartButton() {
startButton.style.display = "none";
crazyButton.style.display = "block";
startingSection.style.display = "none";
}
Now we test if everything is working in localhost:3000:
For this part everything is almost the same with only one difference - we must pass data from our app to the server, process it, and return it to each connected client.
We add a event listener to our crazy button & emit a message containing an object with two values - offsetLeft & offsetTop, which are a Math.random multiplied by the innerWidth & innerHeight of our window - the button's clientWidth & clientHeight:
crazyButton.addEventListener('click', () => {
socket.emit('crazyIsClicked', {
offsetLeft: Math.random() * ((window.innerWidth - crazyButton.clientWidth) - 100),
offsetTop: Math.random() * ((window.innerHeight - crazyButton.clientHeight) - 50)
});
})
The server then receives these values under the form of 'data' variable & emits them back:
socket.on('crazyIsClicked', (data) => {
io.emit('crazyIsClicked', data);
});
Our app.js file then receives the data and input it in the function, which moves the button:
socket.on('crazyIsClicked', (data) => {
goCrazy(data.offsetLeft, data.offsetTop);
});
We create our goCrazy function:
function goCrazy(offLeft, offTop) {
let top, left;
left = offLeft;
top = offTop;
crazyButton.style.top = top + 'px';
crazyButton.style.left = left + 'px';
crazyButton.style.animation = "none";
}
And we test:
Cool, we are all done!
Today you learned what socket.io is, how to pass data, and how to emit & listen for messages. I hope this was helpful and you learned something today! Full project available at my website.
Make sure to check out my other post related to this - The JSourney: Learn with projects, not videos!. I explain why building projects is a better way to study, instead of watching videos all day.
Latest Comments
Nice job, thanks for sharing!
I'm glad you liked it!
Interesting stuff, thanks for sharing.
I am glad it sparked curiosity :))
Thanks for sharing, I will be trying this out with Phaser.js.
Good luck! Keep in mind this is an article I wrote some time ago so it might have errors. It is best to reference to the socketio docs and make sure to check for version match between phaser and socket.
If you need any help, let me know. I would be happy to support!
Good luck and thanks for engaging in my platform, it makes me so so pumped to continue development!
Cheers!
🫵🪨hsbsbsbs