Socket.io 一对一聊天
Socket.io one to one chat
根据文档,一对一聊天发生在我们向特定 socket.id 发送消息时。
例如
io.to(socket.id).emit("event","message")
这只有在两个用户同时连接时才有效。
如果我们要在注册用户可以相互聊天的应用程序中添加聊天功能 (1-1)。什么是 that.I 的最佳解决方案已经使用 io.to(socket.id), 但当其中一位用户离线时 socket.id 不可用。
------------------------------------客户端---- --------------------------
function Chat() {
const [conversations, setConversations] = useState([]);
const [currentChat, setCurrentChat] = useState(null);
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState("");
const [arrivalMessage, setArrivalMessage] = useState(null);
const scrollRef = useRef();
const socket = useRef();
const client = isAuthenticated()
const clientId = isAuthenticated().client._id;
const token = isAuthenticated().client.token
console.log(clientId)
useEffect(() => {
socket.current = io("ws://localhost:8900");
socket.current.on("getMessage", (data) => {
setArrivalMessage({
sender: data.senderId,
text: data.text,
createdAt: Date.now(),
});
});
}, []);
useEffect(() => {
arrivalMessage &&
currentChat?.members.includes(arrivalMessage.sender) &&
setMessages((prev) => [...prev, arrivalMessage]);
}, [arrivalMessage, currentChat]);
useEffect(() => {
socket.current.emit("addUser",clientId );
}, [client]);
useEffect(() => {
getconversation(clientId,token).then((data)=>{
if(data.error){
console.log(data.error)
}else{
console.log(data)
setConversations(data)
}
})
}, [])
useEffect(() => {
const getMessages = async () => {
try {
const res = await axios.get("http://localhost:8080/api/messages/" + currentChat?._id);
setMessages(res.data);
} catch (err) {
console.log(err);
}
};
getMessages();
}, [currentChat]);
useEffect(() => {
scrollRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
const handleSubmit = async (e) => {
e.preventDefault();
const message = {
sender:clientId,
text: newMessage,
conversationId: currentChat._id,
};
const receiverId = currentChat.members.find(
(member) => member !== clientId
);
socket.current.emit("sendMessage", {
senderId: clientId,
receiverId,
text: newMessage,
});
try {
const res = await axios.post("http://localhost:8080/api/messages", message);
setMessages([...messages, res.data]);
setNewMessage("");
} catch (err) {
console.log(err);
}
};
------------------------服务器-------------------- ----------------------
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) => {
//when connect
console.log("a user connected."+socket.id);
//take userId and socketId from user
socket.on("addUser", (userId) => {
addUser(userId, socket.id);
io.emit("getUsers", users);
});
//send and get message
socket.on("sendMessage", ({ senderId, receiverId, text }) => {
console.log("receiverid=====>>>",receiverId)
console.log("users ",users)
const user = getUser(receiverId);
console.log("userSocket Id",user)
io.to(user.socketId).emit("getMessage", {
senderId,
text,
});
});
//when disconnect
socket.on("disconnect", () => {
console.log("a user disconnected!");
removeUser(socket.id);
io.emit("getUsers", users);
});
});
首先需要在您的应用程序中存储消息,以及发送者、接收者和时间戳的详细信息。然后使用网络套接字 / socket.io 来补充功能并实时通知每个用户(如果他们在线)。
这种方法是其他聊天应用程序遵循的方法,例如 Slack。
所以您的应用的主要属性应该是,
- 当用户发送消息时,客户端应该post将其发送到end/server后台进行存储。
- 服务器应通过套接字发出消息。一旦你变得更大并拥有集群,这将通过 pub-sub 服务等变得更加复杂。
- 在线的用户将收到消息并将在聊天屏幕上呈现。
- 如果用户刷新或用户离线并且returns,将从服务器获取该用户的所有消息。
关于发射部分,使用唯一标识符,例如一个或多个用户之间生成的会话的唯一标识符 (uuid),以房间为目标(用户应收听此标识符)或用户 ID 并发射到每个用户id(用户在线后可以收听自己的用户标识符)。消息的详细信息应该足以帮助应用在正确的屏幕上呈现它。
根据文档,一对一聊天发生在我们向特定 socket.id 发送消息时。 例如
io.to(socket.id).emit("event","message")
这只有在两个用户同时连接时才有效。 如果我们要在注册用户可以相互聊天的应用程序中添加聊天功能 (1-1)。什么是 that.I 的最佳解决方案已经使用 io.to(socket.id), 但当其中一位用户离线时 socket.id 不可用。
------------------------------------客户端---- --------------------------
function Chat() {
const [conversations, setConversations] = useState([]);
const [currentChat, setCurrentChat] = useState(null);
const [messages, setMessages] = useState([]);
const [newMessage, setNewMessage] = useState("");
const [arrivalMessage, setArrivalMessage] = useState(null);
const scrollRef = useRef();
const socket = useRef();
const client = isAuthenticated()
const clientId = isAuthenticated().client._id;
const token = isAuthenticated().client.token
console.log(clientId)
useEffect(() => {
socket.current = io("ws://localhost:8900");
socket.current.on("getMessage", (data) => {
setArrivalMessage({
sender: data.senderId,
text: data.text,
createdAt: Date.now(),
});
});
}, []);
useEffect(() => {
arrivalMessage &&
currentChat?.members.includes(arrivalMessage.sender) &&
setMessages((prev) => [...prev, arrivalMessage]);
}, [arrivalMessage, currentChat]);
useEffect(() => {
socket.current.emit("addUser",clientId );
}, [client]);
useEffect(() => {
getconversation(clientId,token).then((data)=>{
if(data.error){
console.log(data.error)
}else{
console.log(data)
setConversations(data)
}
})
}, [])
useEffect(() => {
const getMessages = async () => {
try {
const res = await axios.get("http://localhost:8080/api/messages/" + currentChat?._id);
setMessages(res.data);
} catch (err) {
console.log(err);
}
};
getMessages();
}, [currentChat]);
useEffect(() => {
scrollRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
const handleSubmit = async (e) => {
e.preventDefault();
const message = {
sender:clientId,
text: newMessage,
conversationId: currentChat._id,
};
const receiverId = currentChat.members.find(
(member) => member !== clientId
);
socket.current.emit("sendMessage", {
senderId: clientId,
receiverId,
text: newMessage,
});
try {
const res = await axios.post("http://localhost:8080/api/messages", message);
setMessages([...messages, res.data]);
setNewMessage("");
} catch (err) {
console.log(err);
}
};
------------------------服务器-------------------- ----------------------
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) => {
//when connect
console.log("a user connected."+socket.id);
//take userId and socketId from user
socket.on("addUser", (userId) => {
addUser(userId, socket.id);
io.emit("getUsers", users);
});
//send and get message
socket.on("sendMessage", ({ senderId, receiverId, text }) => {
console.log("receiverid=====>>>",receiverId)
console.log("users ",users)
const user = getUser(receiverId);
console.log("userSocket Id",user)
io.to(user.socketId).emit("getMessage", {
senderId,
text,
});
});
//when disconnect
socket.on("disconnect", () => {
console.log("a user disconnected!");
removeUser(socket.id);
io.emit("getUsers", users);
});
});
首先需要在您的应用程序中存储消息,以及发送者、接收者和时间戳的详细信息。然后使用网络套接字 / socket.io 来补充功能并实时通知每个用户(如果他们在线)。 这种方法是其他聊天应用程序遵循的方法,例如 Slack。
所以您的应用的主要属性应该是,
- 当用户发送消息时,客户端应该post将其发送到end/server后台进行存储。
- 服务器应通过套接字发出消息。一旦你变得更大并拥有集群,这将通过 pub-sub 服务等变得更加复杂。
- 在线的用户将收到消息并将在聊天屏幕上呈现。
- 如果用户刷新或用户离线并且returns,将从服务器获取该用户的所有消息。
关于发射部分,使用唯一标识符,例如一个或多个用户之间生成的会话的唯一标识符 (uuid),以房间为目标(用户应收听此标识符)或用户 ID 并发射到每个用户id(用户在线后可以收听自己的用户标识符)。消息的详细信息应该足以帮助应用在正确的屏幕上呈现它。