//接收到消息 socket.on("message",msg => { console.log("从服务器接收到的消息 : " + msg); //更新内容 content.innerHTML = content.value + msg + "\n"; }); socket.on("disconnect",() => { console.log("与服务器断开连接"); });
为了更能突出websocket的作用,在html代码中,我只使用了一个textarea标签来显示内容,两个input标签用于发送。
使用socket对象的send方法就能使消息在服务器与客户端进行消息传递。
websocket群聊实现
现在我们假设一个场景,有u1和u2两个用户,同时连接到服务器,那么我们怎么使他们互相通信呢,实现的方法及其简单。当u1连接到服务器,在服务器中,使用一个map键值对把与u1对应的socket对象进行保存。
//创建一个用于放置用户对象的map let map = new Map(); //用于记录用户数量的变量,并初始化为0 let userCount = 0; //监听connection 事件 socketServer.on("connection",socket => { console.log("有一用户连接"); map.set(++userCount,socket); //... });
与此同时,u2也连接上服务器,也由该map把与u2与之对应的socket对象进行储存。
现在,u1点击了send按钮发送一条消息至服务器,服务器收到消息后遍历map,转发给所有socket对象,实现群聊的实时通信。
socketServer.on("connection",socket => { console.log("有一用户连接"); map.set(++userCount,socket); //监听客户端来的信息 socket.on("message",msg => { //从客户端接收的消息 //遍历所有用户 map.forEach((value,index,arr) => { value.send(msg); }); }); });
下面我贴上服务端的完整代码,仅供参考
const socket = require("socket.io"); //创建一个websocket服务器 let socketServer = socket.listen(require("http").createServer((req,resp) => { //返回页面 resp.end(require("fs").readFileSync("./socketIOTest1.html")); }).listen(9999,"localhost",() => {console.log("listening");})); //创建一个用于放置用户对象的map let map = new Map(); //用于记录用户数量的变量,并初始化为0 let userCount = 0; //监听connection 事件 socketServer.on("connection",socket => { console.log("有一用户连接"); map.set(++userCount,socket); //监听客户端来的信息 socket.on("message",msg => { //从客户端接收的消息 //遍历所有用户 map.forEach((value,index,arr) => { value.send(msg); }); }); //监听客户端退出情况 socket.on("disconnect",() => { console.log("有一用户退出连接"); }); });
websocket私聊实现
在说私聊的实现之前,我们首先要找到对于每一个用户的唯一标识,在通常的项目开发中,我们都使用用户的用户名进行标识,每个用户通过注册获得与之对应的用户名。将用户名保存在数据库中利用主键防止重复。
实现私聊的方法有很多种,这里我的实现方法是这样的:
① 当用户连接时,把用户的socket端口对象使用map进行储存,储存的key 为用户的socket对象,value为用户的用户名,写一个方法用于更新客户端列表
② 用户默认用户名为 <未命名>,指定自定义用户名时,使用socket.emit方法触发服务端的某个事件,遍历map找到与之对应的key,进行value修改
③ 发送消息时,根据选择列表来指定要发送的人,在服务端,遍历map,找到要发送到的用户名,进行发送,同时更新到自己的聊天框
以上就是私聊的简单实现。
下面看一下具体代码:
//Node.js const socket = require("socket.io"); //创建一个websocket服务器 let socketServer = socket.listen(require("http").createServer((req,resp) => { //返回页面 resp.end(require("fs").readFileSync("./socketIOTest1.html")); }).listen(9999,"localhost",() => {console.log("listening");})); //创建一个用于放置用户对象的map let map = new Map(); //用于记录用户数量的变量,并初始化为0 let userCount = 0; //遍历map let scanMap = func => { try{ map.forEach((value,index,arr) => { func(value,index,arr); }); } catch(e){ if(e.message == "break"){ return; } else{ throw e; } } } //通知客户端弹出对话框 let showDialog = (socket,msg) => { socket.emit("showDialog",msg); } //更新用户列表 let updateList = socket => { let userArr = []; scanMap((value,index) => { if(value != undefined){ userArr.push(value); } }); socket.emit("newUser",userArr); } //监听connection 事件 socketServer.on("connection",socket => { console.log("有一用户连接"); //初始化存储当前socket对象 map.set(socket,"<未命名>"); //将用户信息写入map socket.on("getUser",user => { //修改名称 map.set(socket,user); scanMap((value,index) => { updateList(index); }); }); //通知所有客户端更新列表 scanMap((value,index) => { updateList(index); }); //监听客户端来的信息 socket.on("message",msg => { //从客户端接收的消息 let sender; //遍历所有用户 scanMap((value,index) => { if(index == socket){ sender = value; } }); scanMap((value,index) => { if(msg.person == "all"){ index.send(sender + " : " + msg.msg); } else if(msg.person == value){ socket.send(sender + " : " +msg.msg); index.send(sender + " : " +msg.msg); throw new Error("break"); } }); }); //监听客户端退出情况 socket.on("disconnect",() => { //用户退出,从map里删除该用户 map.set(socket,undefined); //通知所有用户更新列表 scanMap((value,index) => { updateList(index); }); console.log("有一用户退出连接"); }); });
客户端: