A simple example of react app with node.js, express.js, socket.io, created to answer a question in stack overflow.
Sending data from the client to the server and displaying to the terminal using sockets
SERVER - BACK-END
Follow the steps below:
- The Built-in HTTP Module
- Node.js has a built-in module called HTTP, which allows Node.js to transfer data over the Hyper Text Transfer Protocol (HTTP). The HTTP module can create an HTTP server that listens to server ports and gives a response back to the client.
- Use the
createServer()
method to create an HTTP server:
const http = require("http");
const express = require("express");
const app = express();
const server = http.createServer(app);
- Create a utility file with a custom name, here is the name of this
socketUtils.js
:- Here we set up the socket with custom configs, and instantiate.
// <root-project-dir>/utils/socketUtils.js
const socketIO = require("socket.io");
exports.sio = (server) => {
return socketIO(server, {
transports: ["polling"],
cors: {
origin: "*",
},
});
};
exports.connection = (io) => {
io.on("connection", (socket) => {
console.log("A user is connected");
socket.on("message", (message) => {
console.log(`message from ${socket.id} : ${message}`);
});
socket.on("disconnect", () => {
console.log(`socket ${socket.id} disconnected`);
});
});
};
- Well now it's time to use the
socketUtils.js
file:
const http = require("http");
const dotenv = require("dotenv");
const cors = require("cors");
dotenv.config({
path: "./config.env",
});
const express = require("express");
const app = express();
const socketUtils = require("./utils/socketUtils");
const server = http.createServer(app);
const io = socketUtils.sio(server);
socketUtils.connection(io);
- Create a socket middleware:
- To access the socket globally in each request, we create a middleware.
const socketIOMiddleware = (req, res, next) => {
req.io = io;
next();
};
- Use the
listen()
method:- You can write other middleware according to the priority that exists with the routes you need and then put the
listen()
method at the end.
- You can write other middleware according to the priority that exists with the routes you need and then put the
// CORS
app.use(cors());
// ROUTES
app.use("/api/v1/hello", socketIOMiddleware, (req, res) => {
req.io.emit("message", `Hello, ${req.originalUrl}`);
res.send("hello world!");
});
// LISTEN
const port = process.env.PORT || 8000;
server.listen(port, () => {
console.log(`App running on port ${port}...`);
});
The final file should look like this:
// <root-project-dir>/index.js
const http = require("http");
const dotenv = require("dotenv");
const cors = require("cors");
dotenv.config({
path: "./config.env",
});
const express = require("express");
const app = express();
const socketUtils = require("./utils/socketUtils");
const server = http.createServer(app);
const io = socketUtils.sio(server);
socketUtils.connection(io);
const socketIOMiddleware = (req, res, next) => {
req.io = io;
next();
};
// CORS
app.use(cors());
// ROUTES
app.use("/api/v1/hello", socketIOMiddleware, (req, res) => {
req.io.emit("message", `Hello, ${req.originalUrl}`);
res.send("hello world!");
});
// LISTEN
const port = process.env.PORT || 8000;
server.listen(port, () => {
console.log(`App running on port ${port}...`);
});
Finally, to test the server, you can use SocketIO Client Tool online tool, which is very useful.
CLIENT - FRONT-END
After setting up the server, you can use it as follows in the React app and emit an event:
import { useEffect, useRef } from "react";
import "./App.css";
import { io } from "socket.io-client";
function App() {
const socket = useRef();
useEffect(() => {
socket.current = io("ws://localhost:9013");
socket.current.on("connnection", () => {
console.log("connected to server");
});
}, []);
const handleClick = () => {
socket.current.emit("message", new Date().getTime());
};
return (
<div className="App">
<p>Socket.io app</p>
<button type="button" onClick={handleClick}>
Emit a time message
</button>
</div>
);
}
export default App;