Learning Something New👋#
I have been learning React recently, so the main purpose of this project is to familiarize myself with React. I personally like to learn new things while getting hands-on experience. Only by outputting can I have a deeper memory. In addition, I may encounter some pitfalls that I wouldn't encounter just by reading. Since I haven't done much with node.js before, I thought of combining it with a chat room.✌
Since this is my first time using React, if you feel that there is anything that needs to be modified, please feel free to raise an Issue, and I also welcome your star⭐
Project link: ChatRoom
Project screenshots:
Backend#
Backend based on Node.js + Express + Socket.io + MongoDB
I have summarized the operations of Node.js and MongoDB using express in my blog before:
Node.js+express
Node.Js 操作 MongoDB
The new thing I used this time is Socket.io.
Previous Work👇#
Socket.IO is a library that enables real-time, bidirectional and event-based communication between the browser and the server.
This means that Socket.io can achieve real-time bidirectional communication between the server and the client. Before connecting with Socket.io, you need to know about WebSocket. Before WebSocket was introduced, when creating web applications with bidirectional communication mechanisms, only HTTP polling could be used, which resulted in "short polling" and "long polling".
Short polling involves the client regularly polling the server to ask if there is any new information. The disadvantage is obvious. If the polling interval is too long, the information is not real-time enough. If the polling interval is too short, it will consume too much traffic and increase the server's burden.
Long polling is an optimization of short polling and requires corresponding modifications on the server side to support it. However, each request still needs to carry the HTTP request header, and after the long polling connection ends, the accumulated new messages on the server side can only be delivered when the client connects next time.
The WebSocket protocol was born to solve the pain points of long polling. It is based on the TCP protocol and is a full-duplex communication technology that reuses the HTTP handshake channel. The only relationship with HTTP is that its handshake request can be parsed by an HTTP server as an Upgrade request, and it uses the same port as HTTP.
Next is Socket.io, which is based on engine.io at the bottom. It encapsulates WebSocket and shields the underlying details, making the top-level calls very simple. At the same time, it supports many polling mechanisms and other communication methods. When the environment does not support WebSocket, it can automatically choose the best way to achieve real-time communication over the network.
Usage#
Import io and set the port, then listen for the connect event:
const server = require('http').Server(app);
const io = require('socket.io')(server);
server.listen(3001); // Set the port to 3001
io.on(('connection', socket=>{
………………
})
Then, use the two most important APIs, emit and on, to send and listen for events:
- socket.emit(eventName, [...args]): Emit (trigger) an event
- socket.on(eventName, callback): Listen for an event emitted by emit
// Listen for the xxx event and output the data object passed in
socket.on('xxx',data=>{
console.log(data);
})
// Send the xxx event and pass an object with a name property
socket.emit('xxx',{name:'magren'})
Other methods used:
- socket.join(id): Join a room with the id
- socket.broadcast.to(id).emit(): Broadcast to everyone in the room with the id except for 'me'
- io.sockets.in(id).emit(): Broadcast to everyone in the room with the id
Frontend#
Frontend based on React + Redux + Typescript + Antd
Sending and listening for messages from the backend is simple. Just import socket.io-client and then use emit to send and on to listen for events.
const socket = require('socket.io-client')('ws://localhost:3001',{transports: ['websocket']})
// Listen for chat_message and update the state with the received data
socket.on('chat_message',(data: mesItem)=>{
this.setState({
message:[data,...this.state.message]
});
})
// Send a join event to join a group
socket.emit('join', {
roomId:this.props.match.params.roomId,
userName:this.props.state.name,
userId:this.props.state.id
})
// Send a message
socket.emit('mes',{
roomId:this.props.match.params.roomId,
userName:this.props.state.name,
userId:this.props.state.id,
mes:this.state.msg
})
About Redux#
The concept of redux is similar to vuex. They are both state management libraries and store the state in memory (which will be reset when refreshed). They define global state and trigger state changes through actions. However, there are also differences. Vuex allows data to be mutable and directly modified, while Redux is immutable and replaces the old state with a new state.
This project uses two libraries: react-redux and redux-thunk.
After using react-redux, the process is greatly simplified. The three main functions of the store: dispatch, subscribe, and getState are implemented by it. It also provides Provider and Connect, the former being a component and the latter being a function.
The general process is that the Provider component accepts the redux store as props and passes it down through context. The connect function receives the store passed out by Provider and passes the state and actionCreator as props to the component. The component can then trigger the reducer function by calling the action in props, which returns a new state. Connect listens for changes and calls setState to update the component and pass in the new state.
The purpose of redux-thunk is to make store.dispatch able to accept a function/object as middleware.
It allows store.dispatch, which originally only accepts objects, to accept objects/functions. If a function is received, it will be automatically executed without triggering a store update.
Finally💻#
Thanks to search engines like Google and Baidu, and Google Translate😵
And thanks to the reference and summary of the react-pxq project by bailicangdu😘