As the web evolves, so do the technologies that power it. Although RESThas remained the default choice for web services architectures, most modern applications require features that REST would not be able to reliably provide. These features have one thing in common, real-time. Whether it is a notification system, a chat-box, or an activity tracker, a constant stream of information is required. This is exactly where sockets shine, being able to send data back and forth without having to re-initialize a connection for each action. One of the best libraries for handling web sockets is Socket.IO.
We will be using React for the front-end and Node.js for the back-end, Express as the web framework, MongoDB as database and Mongoose as ODM. We will then be able to connect the two ends using Socket.IOamazing API.
I will assume that you have already installed the latest version of Node.js, as well as the specific MongoDB distribution for your own OS. Or, you can simply use Atlas.
Let’s go ahead and make a new folder, chat-demo/. Inside of it we can create two sub-folders: frontend/ and backend/, which will contain their respective source code:
You can name the folders however you’d like, of course.
We will create a new React application using create-react-app. Type the following command inside the frontend/ folder:
$ npx create-react-app .
We can remove a few files that we do not need.
Inside public/, let’s delete everything except index.html.
Inside src/, delete everything except App.js, index.css and index.js.
Deleting said files is not mandatory either, but will leave us with a cleaner structure.
First of all, let’s install the socket.io-client package by typing the following command inside the_ frontend/_ folder:
$ npm i socket.io-client
We can now write our chat component inside App.js.
import React, { useState, useEffect } from "react";
import socketIoClient from "socket.io-client";
const socket = socketIoClient("http://localhost:8463", { autoConnect: false });
const Message = ({ msg }) => {
return (
<div className="msg">
<span> { new Date(msg.date).toLocaleDateString() } </span>
<span> { msg.content } </span>
</div>
);
};
const MessageBox = () => {
const [value, setValue] = useState("");
const postMessage = e => {
e.preventDefault();
if (!value) return;
socket.emit("message", value);
setValue("");
};
return (
<form onSubmit={ postMessage }>
<input type="text" className="input" placeholder="message"
value={ value } onChange={ e => setValue(e.target.value) }
/>
</form>
);
};
const Chat = () => {
const [messages, setMessages] = useState([]);
const addMessage = (msg) => {
setMessages(oldMessages => [...oldMessages, ...(Array.isArray(msg) ? msg.reverse() : [msg])]);
};
useEffect(()=> {
socket.on("latest", (data) => {
// expect server to send us the latest messages
addMessage(data);
});
socket.on("message", (msg) => {
addMessage(msg);
});
socket.connect();
}, []);
return (
<div>
<div id = "msgBox">
{ messages.map((msg, index) => <Message msg={msg} />) }
</div>
<MessageBox />
</div>
);
};
export default Chat;
#socketio #programming #mongodb #react #nodejs