Why web sockets?

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.

The stack

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.

Project structure

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:

Image for post

You can name the folders however you’d like, of course.

Setting up React

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.jsindex.css and index.js.

Image for post

Deleting said files is not mandatory either, but will leave us with a cleaner structure.

Creating our chat component

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

Let’s Build a Real-Time Chat Application using Socket.IO, React, Node.js and MongoDB
22.45 GEEK