Learn to Code via Tutorials on Repl.it!

← Back to all posts
Create Multiplayer Websites w/out a Server!
zakaton (9)

Create Multiplayer websites with Socket.IO without setting up your own Node.js Server!

Socket.io is a popular Node.js package for creating multi-user applications (messaging, games, collaborative editing, etc).

However, you'll need to setup a Node.js server to start connecting users. That's why we set up our own Socket.IO Server so you don't have to!

In this tutorial you'll learn how to do the following:
1. Connect to our Socket.IO server
2. Send messages between users
3. Create a simple chat application


Table of Contents:

📦 Setting up
📡 Connecting to our Server
🗣️ Sending Messages
👂 Receiving Messages
🚪 Joining a Room
💬 Creating a Simple Chat Application
📥 Download our Template!
🙌 Possibilities


📦 Setting up

Create a new HTML, CSS, JS Repl

In your new Repl, add the Socket.IO package (type in "socket.io" in the Packages section in the sidebar and select the result titled "socket.io: node.js realtime framework server").

Alternatively, you can add the Socket.IO library manually by inserting the following <script></script> tag:

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

This will add an io object in the global scope of the page, exposing the Socket.IO Client API


📡 Connecting to our Server

Create a socket instance that represents your connection to our Node.js Socket.IO Server, passing in the url of the repl.it it's hosted at:

	let socket = io("https://socketio.zakaton.repl.co");

Once connected to the server, the socket instance will trigger the 'connect' event, which you can listen for using socket.on(eventName, callback):

	socket.on('connect', () => {
		console.log('connected!');
	});

Each socket instance has a unique socket.id property, which you can use to directly message others.


🗣️ ️️️Sending Messages

After connecting to our server, you can either send a message to everyone or message a user directly via socket.emit():

	socket.on('connect', () => {

		// send a message to everyone
		socket.emit('message' {
			message : "Hello!"
		});

		// send a message to a particular user if you have their socket.id
		socket.emit('direct-message', {
			message : "Hello!",
			id : remoteSocketId // you can listen for the 'user-connect' event to get their socket.id
		});

	});

👂 Receiving Messages

You can receive messages via socket.on(eventName, callback):

	socket.on('connect', () => {
		
		// receive a message from anyone
		socket.on('message', message => {
			console.log("received a message", message);
		});

		// receive a direct message
		socket.on('direct-message', message => {
			console.log("received a direct message", message);
		});

		// know when a user has joined the server
		socket.on('user-connect', data => {
			const {id} = data;
			console.log(`user ${id} has connected to the server`);
		});

		// or left the server
		socket.on('user-disconnect', data => {
			const {id} = data;
			console.log(`user ${id} has disconnected from the server`);
		});

	});

🚪 Joining a Room

To prevent users in one repl receiving messages from users in another repl, you can join a room, allowing you to send messages to users in a particular room to limit who recieves it.

	socket.on('connect', () => {
		
		// join a room, using the url of the repl as the room name
		socket.emit('join', {
			room : location.href
		});

		// message everyone in a room
		socket.emit('message-room', {
			message : "Hello!",
			room : location.href,
		});

		// receive a message sent to any room the user is in
		socket.on('message-room', message => {
			console.log("received message", message);
		});

		// know when someone has joined the room
		socket.on('join-room', data => {
			const {id, room} = data;
			console.log(`user ${id} has joined room "${room}"`);
		});

		// or left the room
		socket.on('leave-room', data => {
			const {id, room} = data;
			console.log(`user ${id} has left room "${room}"`);
		});
	});

💬 Creating a Simple Chat Application

This assumes you've already done "Setting up" and "Connecting to our Server"

Add elements:

	<div id="chat"></div>
	<input disabled id="postInput" type="text"> <button id="postButton">post</button>

Send a post when they hit the "postButton" button:

	let chat = document.getElementById("chat");
	let postInput = document.getElementById("postInput");
	let postButton = document.getElementById("postButton");

	// enable the post <button> when there's text in the <input>
	postInput.addEventListener("input", event => {
		postButton.disabled = (postInput.value.length == 0);
	});

	postButton.addEventListener("click", event => {

		// send a 'message-room' message to the socket.io server
		socket.emit('message-room', {
			room : location.href,
			message : postInput.value,
		});

		// also we don't receive our own message from the server so we'll need to add the message to the chat ourselves
		chat.innerText += postInput.value;

		// clear the <input> and disable the post <button> again
		postInput.value = '';
		postButton.disabled = true;
	});

Receive posts and add them to the chat:

	// you may want to put this in the socket.on('connect') callback
	socket.on('message-room', message => {
		chat.innerText += message;
	});

Here you can play with the full chatroom repl that also adds the user's socket.id to each post so you can see who said what


📥 Download our Template!

We created a template repl.it webpage you can fork!

This template adds the Socket.IO Client API, creates a socket instance that connects to our server, and creates a room unique to your repl name.

You can send messages to other users on the same repl page using the location.href property as the room name:

	socket.emit('message-room', {
		room : location.href,
		message : "Hello!"
	});

🙌 Possibilities

Not only can you send messages between users on the same repl, but you can literally send messages to anyone connected to our Socket.IO Server! What does this mean?

This means you can create repl's that interact with other repl's, where one repl can send a message to users in another repl by specifying that repl's url as the room. Or you can just emit a message to all users on all repls using socket.emit('message', myMessage).

You can then imagine a repl's set of message names as its API. For instance, you can create a repl that sends messages to our chat application repl, adding extra functionality like automated messaging. A repl could also join the chat repl's room and listen for posts, e.g. to display a nicer UI for displaying posts.

Imagine creating a multiplayer game where players message player actions (movement, shooting, etc). A third-party repl could also be listening for these messages and create a scoreboard or map of the players that people could use to visualize gameplay. Players can also use third-party repl's that can produce messages on behalf of the player (like a third-party turbo controller for a game console)

Commentshotnewtop
Highwayman (1367)

Quick question, what is the Set for? You don’t seem to use it for anything but to add and delete it from the set and that’s it.. what am I missing?

zakaton (9)

@Highwayman I added it in the beginning thinking I'd need it at some point, but I never got around to using it.

Thanks for pointing that out - just removed it!

Highwayman (1367)

It’s a really sick thing though. :)

Highwayman (1367)

Hmm I feel like it’s skipping over the fact that socket.io sends events and now you have to make your own event handler and stuff, why don’t you make it so people can make custom events for a room or socket?

socket.on("cust-evnt",(data) => {
  socket.on(data.evntName, eval(data.handler) );
});
zakaton (9)

@Highwayman you can do that by adding an eventName property in the socket.emit() message:

socket.emit('message', {
    message : myMessage,
    eventName: 'custom-event'
});

// now others can receive that event
socket.on('custom-event', message => {
    console.log("received message", message);
});

which works with general messages, messaging rooms, or direct messaging. If you omit the eventName property then it defaults to 'message', 'message-room', and 'direct-message' respectively. (I omitted it from the tutorial for simplicity)

nt998302 (173)

how duz dis wurk :\

Highwayman (1367)

@nt998302 are you asking how to use it or how to make it.

nt998302 (173)

@Highwayman Never mind, I'm starting to learn python flask.