源码 koa-mongodb-template
ws 模块
下载
npm install ws
简单使用
服务端代码
const WebSocket = require("ws");
const WebSocketServer = WebSocket.WebSocketServer;const wss = new WebSocketServer({ port: 8080 });// 监听客户端连接
wss.on("connection", function connection(ws) {// 客户端连接后,发送消息ws.send("hello socket");// 监听客户端发来的消息ws.on("message", function message(data) {console.log("data", data, data.toString());// 广播发送给全部客户端wss.clients.forEach(function each(client) {// 判断是否是自己,判断是否在线,发送给在线的客户端if (client !== ws && client.readyState === WebSocket.OPEN) {// 不使用二进制数据client.send(data, { binary: false });}});});
});
客户端代码
<body><h1>socket</h1><button class="btn">发送</button><script>const socket = new WebSocket("ws://localhost:8080")const btn = document.querySelector('.btn')btn.addEventListener('click', () => {socket.send("客户端发送了消息")})socket.onopen = () => {console.log('连接成功');}socket.onmessage = (msg) => {console.log('message', msg, msg?.data);}socket.onerror = () => {console.log('err');}</script>
</body>
apipost 连接测试
实现用户验证
const WebSocket = require("ws");const { checkToken } = require("../utils");const WebSocketServer = WebSocket.WebSocketServer;
const wss = new WebSocketServer({ port: 8080 });wss.on("connection", function connection(ws, req) {// 获取 token 参数const token = new URL(req.url, "http://localhost:3000").searchParams.get("token");// 获取用户信息const userInfo = checkToken(token);if (userInfo) {ws.send(`欢迎回来,${userInfo?.userName}`);// 向 ws 添加 userInfo 属性,值为 userInfo,可通过 wss.clients 查看ws.userInfo = userInfo} else {ws.send("未登录");}});
实现获取用户列表群聊私聊
WebSocket 有:message 事件 监听消息,send 方法 发送消息
如何使用这两个更方便的前后端交互,需要在发送消息做处理
定义 json 数据
- type 类型 1:获取用户列表 2:群聊 3:私聊
- data 返回的数据
{"type": 1,"data": null
}
socket.io
下载
npm install socket.io
使用
服务端代码片段
const { checkToken } = require("../utils");function main(app, port) {const { createServer } = require("http");const { Server } = require("socket.io");const httpServer = createServer(app.callback());const io = new Server(httpServer, {/* options */});// 连接io.on("connection", (socket) => {// 获取 tokenconst token = socket.handshake.query?.token;// 解析用户信息const userInfo = checkToken(token);if (userInfo) {// 向 socket 添加 userInfo 属性socket.userInfo = userInfo;// 自定义事件名 user,参数可直接传 json 格式socket.emit("user", { data: userInfo, msg: "获取信息成功" });} else {socket.emit("error", { data: null, msg: "token 错误" });}// 获取列表 data 前端传递的参数socket.on("list", (data) => {const list = Array.from(io.sockets.sockets).map((item) => item[1].userInfo);console.log("list", list);});// 获取私聊socket.on("single", (data) => {console.log("single", data);Array.from(io.sockets.sockets).forEach((item) => {if (item[1].userInfo?._id === data.id) {item[1].emit("single", {});}});});// 获取群聊socket.on("group", (data) => {console.log("group", data);// 给所有人发io.sockets.emit("group", {});// 发送除了自己,其他所有// socket.broadcast.emit("group", {});});socket.on("disconnect", (data) => {console.log("disconnect", data);});});httpServer.listen(port, () => {console.log(`http://127.0.0.1:${port}`);});
}function sendAll(io) {const list = Array.from(io.sockets.sockets).map((item) => item[1].userInfo);// 群发io.sockets.emit("list", { data: list });
}module.exports = main;
apipost 测试