Socket.io + Knex 实现私聊聊天室
私密 Room
在开始做私聊功能之前,要掌握 Socket.io 的 Room 概念,当一个客户端连接到服务器时就会产生一个唯一的标识符,作为客户端的 ID。socket.id
就可以拿到标识符:
server.on("connection", (socket: any) => {
console.log(socket.id);
});
一个socket.id
就是一个私密的 Room,客户端 A 拿到客户端 B 的私密 Room,就可以通过socket.to(room).emit('echo private', "Hello")
向客户端 B 发送私密信息。
公共 Room
任意一个字符都可以作为公共 Room,区别于私密 Room。客户端通过socket.join(room)
加入公共 Room,服务器就可以使用server.to(room).emit('public')
发送群聊消息的事件,而客户端只需要监听这个事件就可以拿到群聊消息。下图是公共 Room 的结构图:
在本篇博文中,这一小节只是介绍 Socket.io 中私密 Room 和公共 Room 的区别。
搭建服务器
下面是服务器转交私密消息的实现步骤和代码:
- 服务器监听连接事件,当客户端 A 连接之后,服务器就监听客户端 A 的私密信息事件。
- 当客户端 A 发送私密信息事件之后,服务器就把私密信息转发给客户端 B。
server.on("connection", (socket: any) => {
socket.on("emit-private", (e: any) => {
socket.to(e.socket_id).emit("echo-private", e);
});
});
搭建客户端
客户端的实现步骤稍微复杂一些,客户端发送的私密消息需要封装到类,通过 emit 发送给服务器,再由服务器去转交消息给目标客户端。
封装消息类
export class Message {
public username: string;
public text: string;
public avatar: string;
public popColor: string;
public type?: string;
public socket_id?: string;
constructor(username: string, text: string, avatar: string, popColor: string, type?: string, socketId?: string) {
this.username = username;
this.text = text;
this.avatar = avatar;
this.popColor = popColor;
this.type = type;
this.socket_id = socketId;
}
}
接收私密消息一方需要知道消息的用户名、消息文本、头像、Socket ID(私密 Room 标识符),其他的字段忽略不看。
发送私密消息
下面是聊天室的 setup(组合式)代码,忽略了大量细节,只保留了核心代码:
- 导入 socket-client 模块,连接服务器。
- 客户端中输入好消息之后,点击按钮触发事件,客户端发送
emit-private
给服务器。 - 客户端监听服务器转交的私密消息。
import { onMounted, ref } from "vue";
import { io } from "socket.io-client";
import { Message } from "../typescript/standard";
const socket = io("http://localhost:3000");
const methods = {};
onMounted(() => {
socket.on("echo-private", (e) => {
console.log(e);
});
methods.onSendText = (text: string) => {
let message = new Message(username, text, avatar, popColor, "others", socket_id);
socket.emit("emit-private", message);
};
});
项目演示
目前有三个客户端已经连接到服务器,下图是每一个客户端的私密 Room 标识符,它是唯一的,且由服务器分配的:
下图是两个客户端进行私聊,另一个客户端不能接收消息的演示截图:
左边是客户端 A,右上是客户端 B,右下是客户端 C。客户端 A 给客户端 B 互相发送私密消息,客户端 C 不能接收。
写在最后
想要查看完整的实现步骤,如果喜欢的话,请给我的仓库点一个 Star 吧,再给博文也点个赞!!!
- 前端项目:chatroom
- 后端项目:chatroom-serve
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步