在uniapp中,可以做很多有趣的app,最近也是想起要做一个通信功能的app,于是联想到了微信的通信功能,想通过这个项目来了解通信的原理是什么。
看一下最终的两人聊天的效果:
大家可以看上面的图,就大概知道双方是如何通信的(这里项目指的是私聊,不是群聊),原理就是客户端发送请求给服务端,服务端去指定用户的ID去发送给指定的用户消息实现双方的实时通信。
这里推荐使用封装的第三方库基于websocket的socket.io库地址:https://socket.io/zh-CN/
前端部分我们使用uniapp来实现页面的渲染。
前端使用第三方库weapp.socket.io官网:https://ext.dcloud.net.cn/plugin?id=109
引入自己项目文件就可以使用了
这里主要是一对一的聊天功能,因为默认websocket是全部转发机制,所以我们要通过id号来解决这个问题。下面看一下代码:
这个是登录时候建立与服务器的连接:
success: (res => {
console.log(res)
if (res.data == true) {
// io("http://10.55.230.22:8002");
getApp().globalData.socket = io("http://8.130.120.38:8002");
console.log(getApp().globalData.socket)
uni.request({
url: "http://8.130.120.38:5001/userID",
data: {
email: that.email
},
success: (res => {
console.log("个人的id:" + res.data);
getApp().globalData.socket.emit("login", res.data);
getApp().globalData.email = that.email;
uni.showToast({
title: '登录成功!',
icon: 'none',
mask: true
});
setTimeout(() => {
uni.switchTab({
url: "/pages/home/home"
})
}, 1500)
})
})
};
if (res.data == false) {
uni.showToast({
title: '账号密码不正确!',
icon: 'none',
mask: true
});
};
if (res.data.code == "账号不存在") {
uni.showToast({
title: '账号不存在!',
icon: 'none',
mask: true
});
}
})
node后端接收:
//websocket实现的消息实时通信
const { createServer } = require("http");
const { Server } = require("socket.io");
const httpServer = createServer(app);
const io = new Server(httpServer, { /* options */ });
io.on("connection", (socket) => {
console.log("连接成功");
});
指定id发送:
// 向指定用户发送消息
function sendMessageToUser(userId, message) {
const socketId = connectedUsers[userId];
if (socketId) {
console.log("sendMessageToUser发送");
if(message.TextType==1){
message.sendText = sendTexts;
io.to(socketId).emit('message', message);
}
else if(message.TextType==2){
message.sendText.voice = sendTexts;
io.to(socketId).emit('message', message);
}else{
io.to(socketId).emit('message', message);
}
}else{
}
}
完整的代码大家会看的比较清楚一些:
//websocket实现的消息实时通信
const { createServer } = require("http");
const { Server } = require("socket.io");
const httpServer = createServer(app);
const io = new Server(httpServer, { /* options */ });
const connectedUsers = {}; // 存储已连接用户及其Socket标识符的对象
// 向指定用户发送消息
function sendMessageToUser(userId, message) {
const socketId = connectedUsers[userId];
if (socketId) {
console.log("sendMessageToUser发送");
if(message.TextType==1){
message.sendText = sendTexts;
io.to(socketId).emit('message', message);
}
else if(message.TextType==2){
message.sendText.voice = sendTexts;
io.to(socketId).emit('message', message);
}else{
io.to(socketId).emit('message', message);
}
}else{
}
}
io.on("connection", (socket) => {
console.log("连接成功");
socket.on("message",data=>{
// console.log(data);
const { userId, message } = data;
console.log(userId);
sendMessageToUser(userId, message);
});
// 用户连接时保存其Socket标识符和用户ID的对应关系
socket.on('login', (userId) => {
connectedUsers[userId] = socket.id;
console.log(connectedUsers);
});
});
httpServer.listen(8002);
前端完整接收:
//websocket消息接收
getmessage() {
let that = this;
getApp().globalData.socket.on("message", data => {
that.unshiftmsg.push(data);
console.log(data)
});
},