What are WebSockets?
Socket.IO enables real-time, bidirectional and event-based communication.
It works on every platform, browser or device, focusing equally on reliability and speed.
Socket.IO allows you to bridge the gap between clients and servers, or any other kind of device. It works on every platform, browser or device, focusing equally on reliability and speed. Learn how easy it is to integrate socket functionality into your web app in under ten minutes!
Now let us see how to use Socket.io
The tools that we are going to use are,
- Nodejs and Express
- Reactjs
- and obviously Socket.io 😂
Let us start
We will be building a simple chat app using Nodejs and React.
First initialize our server
npm init
Then install the dependencies
npm install express socket.io
Run the server
node server.js
Let start coding our server now,
const express = require("express");
const socket = require("socket.io");
// App setup
const PORT = 5000;
const app = express();
const server = app.listen(PORT, function () {
console.log(`Listening on port ${PORT}`);
console.log(`http://localhost:${PORT}`);
});
// Static files
app.use(express.static("public"));
// Socket setup
const io = socket(server);
io.on("connection", function (socket) {
console.log("Made socket connection");
const { roomId } = socket.handshake.query;
socket.join(roomId);
// Listen for new messages
socket.on(NEW_CHAT_MESSAGE_EVENT, (data) => {
io.in(roomId).emit(NEW_CHAT_MESSAGE_EVENT, data);
});
// Leave the room if the user closes the socket
socket.on("disconnect", () => {
socket.leave(roomId);
});
});
});
Once the socket is open, it listens for the event we emit in the React app. The message, that is carried by that event, is then forwarded to all users in the same room by emitting another event. The client picks up the event and adds the message to the array of all messages.
Let us create the front-end now using Reactjs,
Set up the react evironment using create-react-app
npx create-react-app socketio-chat
Install the dependencies
npm install socket.io-client react-router-dom
Start the app,
npm start
We will be creating two pages
- Home page - To enter roomId
- Chat Page - To chat
App.js
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import "./app.css";
import Home from "./pages/Home";
import ChatRoom from "./page/ChatRoom";
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/:roomId" component={ChatRoom} />
</Switch>
</Router>
);
}
export default App;
Home.js
import React,{useState} from "react";
import { Link } from "react-router-dom";
const Home = () => {
const [roomName, setRoomName] = useState("");
const handleRoomNameChange = (event) => {
setRoomName(event.target.value);
};
return (
<div className="home-container">
<input
type="text"
placeholder="Room"
value={roomName}
onChange={handleRoomNameChange}
className="text-input-field"
/>
<Link to={`/${roomName}`} className="enter-room-button">
Join room
</Link>
</div>
);
};
export default Home;
Chat Room
import React from "react";
import useChatMessage from "../hooks/useChatMessage";
const ChatRoom = (props) => {
const { roomId } = props.match.params; // Gets roomId from URL
const { messages, sendMessage } = useChatMessage(roomId); // Creates a websocket and manages messaging
const [newMessage, setNewMessage] = React.useState(""); // Message to be sent
const handleNewMessageChange = (event) => {
setNewMessage(event.target.value);
};
const handleSendMessage = () => {
sendMessage(newMessage);
setNewMessage("");
};
return (
<div className="chat-room-container">
<h1 className="room-name">Room: {roomId}</h1>
<div className="messages-container">
<ol className="messages-list">
{messages.map((message, i) => (
<li
key={i}
className={`message-item ${
message.ownedByCurrentUser ? "my-message" : "received-message"
}`}
>
{message.body}
</li>
))}
</ol>
</div>
<textarea
value={newMessage}
onChange={handleNewMessageChange}
placeholder="Write message..."
className="new-message-input-field"
/>
<button onClick={handleSendMessage} className="send-message-button">
Send
</button>
</div>
);
};
export default ChatRoom;
Let us create a hook to manage the socket and incomming-outgoing messages,
useChatMessage.js
import { useEffect, useRef, useState } from "react";
import socketIOClient from "socket.io-client";
const NEW_CHAT_MESSAGE_EVENT = "newChatMessage"; // Name of the event
const SOCKET_SERVER_URL = "http://localhost:5000";
const useChatMessage= (roomId) => {
const [messages, setMessages] = useState([]); // Sent and received messages
const socketRef = useRef();
useEffect(() => {
// Creates a WebSocket connection
socketRef.current = socketIOClient(SOCKET_SERVER_URL, {
query: { roomId },
});
// Listens for incoming messages
socketRef.current.on(NEW_CHAT_MESSAGE_EVENT, (message) => {
const incomingMessage = {
...message,
ownedByCurrentUser: message.senderId === socketRef.current.id,
};
setMessages((messages) => [...messages, incomingMessage]);
});
// Destroys the socket reference
// when the connection is closed
return () => {
socketRef.current.disconnect();
};
}, [roomId]);
// Sends a message to the server that
// forwards it to all users in the same room
const sendMessage = (messageBody) => {
socketRef.current.emit(NEW_CHAT_MESSAGE_EVENT, {
body: messageBody,
senderId: socketRef.current.id,
});
};
return { messages, sendMessage };
};
export default useChatMessage;
That's its friends we have created our real-time-chat-app using node-react.
P.S I have skipped the CSS, you guys can add the color to it 😁
For more information you can visit socket.io official web page Socket.io
Top comments (1)
Nice, I have build a Realtime code editor project called Code-Sync.
🔮 Features of project: