一、实现
socket.js
1. 使用的模块
socket.io: github.com/socketio/so…
nodemon: www.npmjs.com/package/nod…
yarn add nodemon socket.io
2. 具体实现
1. 初始化npm
npm init
2. 修改package.json
文件
{
"name": "soket",
"version": "1.0.0",
"description": "chat",
"main": "index.js",
"scripts": {
"start": "nodemon index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"nodemon": "^2.0.20",
"socket.io": "^4.5.4"
}
}
3. socket启动文件
// 开启socket
const io = require("socket.io")(8900, {
// 允许这个地址访问
cors: {
origin: "http://localhost:3000",
},
});
// 所有在线人的存储
let users = [];
const addUser = (userId, socketId) => {
!users.some((user) => user.userId === userId) &&
users.push({ userId, socketId });
};
const removeUser = (socketId) => {
users = users.filter((user) => user.socketId !== socketId);
};
const getUser = (userId) => {
return users.find((user) => user.userId === userId);
};
io.on("connection", (socket) => {
//添加用户信息 和 当前socket的ID
socket.on("addUser", (userId) => {
addUser(userId, socket.id);
io.emit("getUsers", users);
});
//监听客户端的信息。并且根据socketID发送出去
socket.on("sendMessage", ({ senderId, receiverId, text }) => {
const user = getUser(receiverId);
io.to(user.socketId).emit("getMessage", {
senderId,
text,
});
});
//断开链接重新发送在线人数
socket.on("disconnect", () => {
removeUser(socket.id);
io.emit("getUsers", users);
});
});
client
前端
1. 使用的模块
socket.io-client: github.com/socketio/so…
yarn add socket.io-client
2. 具体实现
1. 消息界面messenger.jsx
import { io } from 'socket.io-client';
// 初始化
useEffect(() => {
// 建立socket链接
socket.current = io('ws://localhost:8900');
// 开启监听socket发送的信息
socket.current.on('getMessage', (data) => {
setArrivalMessage({
sender: data.senderId,
text: data.text,
createdAt: Date.now(),
});
});
}, []);
// 用于记录链接用户信息
useEffect(() => {
// 每个用户登录都会记录一个
socket.current.emit('addUser', user._id);
// 获取所有在线的人
socket.current.on('getUsers', (users) => {
setOnlineUsers(
user.followings.filter((f) => users.some((u) => u.userId === f))
);
});
}, [user]);
// 用接口发消息时 也对socket 发一次请求
const handleSubmit = async (e) => {
e.preventDefault();
const message = {
sender: user._id,
text: newMessage,
conversationId: currentChat._id,
};
const receiverId = currentChat.members.find(
(member) => member !== user._id
);
// socket 发一次请求
socket.current.emit('sendMessage', {
senderId: user._id,
receiverId,
text: newMessage,
});
// 接口也发一次
try {
const res = await axios.post('/messages', message);
setMessages([...messages, res.data]);
setNewMessage('');
} catch (err) {
console.log(err);
}
};
二、问题
1. 连接不上数据库
1. 报错信息
MongooseError: Operation ‘users.insertOne()’ buffering timed out after 10000ms
2. 解决方案
1. 新建云端数据库
1. 官网地址
2.创建一个Database
3. 获取链接
2. 在api项目中创建.env
文件
MONGO_URL = mongodb+srv://jrl:qq2236954952@cluster0.ziak0ct.mongodb.net/?retryWrites=true&w=majority