/* TODO: * 在指定的房间内广播数据 BroadcastInRoom(roomid, msg) * 探索出能解决将同一roomid的客户加入房间的问题的方法 FIXME: * 暂无待修正 XXX: * 房间功能 */ // 导入模块 var WebsocketServer = require('websocket').server; var http = require('http'); const { connection } = require('websocket'); //const { client } = require('websocket'); // 创建http服务器(用于承载WS) var server = http.createServer(); // 端口设置端口 const PORT = 3000 || process.env.PORT // 客户端列表 var clientsList = new Map(); // 初始化public,这将是未指定房间默认加入的房间 clientsList.set('public',[]); // http绑定端口 server.listen(PORT, () => { console.log("Server running on http://localhost:" + PORT); }); // 在http服务器上运行WS服务器 var wsServer = new WebsocketServer({httpServer:server}); // 当客户端连入时 wsServer.on('request', (websocketRequest) => { var connection = websocketRequest.accept(null, 'accepted-origin'); //将客户端插入终端列表 clientsList.get('public').push(connection); console.log('A client connected'); // 当收到消息时 connection.on('message', (msg) => { // 判断消息类型 if(msg.type == 'utf8'){ // 过滤非法数据 try { /* 定义的数据传送格式规范(JSON): tag:数据标签 msg:数据内容 opt:Boolean,确认是否为执行操作,操作tag与用户传输的tag重合。 args: opt参数 */ // 解析数据 cd = JSON.parse(msg.utf8Data); // 开发中,将客户端加入某个房间 if(cd.tag == 'setRoom' && cd.opt == true){ joinToRoom(cd.msg, connection) } // 房间内群发 if(cd.tag == 'roomcast' && cd.opt == true && cd.arg != undefined){ console.log('Cast!') BroadcastInRoom(cd.arg.roomid, 'cast', cd.msg); }else if(cd.opt == true && (cd.arg == undefined || cd.arg == "")){ // 无参数提示 console.log('Cannot GET arg'); }else{ console.log('Unknown ERROR'); } // 常规消息将对所有 if(cd.opt == null || cd.opt == false){ // clientsList.forEach(element => { // element.sendUTF(cd.msg); // }); broadCastForAll(cd.msg) } console.log(cd); } catch (error) { console.log(error); console.error('Illegal Data'); } }else{ console.log(msg); } }); connection.on('close', (reasonCode, description) => { console.log('A client disconnected'); }); }) // 房间内消息广播 function BroadcastInRoom(roomid, tag, msg){ // for(var i = 0; i < clientsList.length; i++){ // if(clientsList[i].roomid == roomid){ // clientsList[i].send(JSON.stringify({'tag': tag, 'msg': msg})); // } // } clientsList.forEach(element => { if(element.roomid == roomid){ element.send(JSON.stringify({'tag': tag, 'msg': msg})); } }); console.log("CAST!!!!") } function joinToRoom(roomid, connection){ // 如果客户端对象没有设置过roomid属性则增设 if(connection.roomid == undefined){ connection.roomid = []; //connection.roomid = cd.msg; connection.roomid.push(roomid) } // 如果未创建过该房间,则创建 if(!clientsList.has(roomid)){ clientsList.set(roomid,[]); console.log('Create Room: ' + roomid); } // 将client加入到指定roomid的list clientsList.get(roomid).push(connection); // 将传进来的roomid属性写入 connection.roomid.push(cd.msg); console.log("Set! roomid = " + connection.roomid); } // 离开房间 function leaveFromRoom(roomid, connection){ // 如果客户端对象没有设置过roomid属性则返回错误信息 if(connection.roomid == undefined){ return false; } // 将client从ClientsList指定的房间roomid中移除并移入默认的public --可能会有问题 --Written By Copilot clientsList.get(roomid).splice(clientsList.get(roomid).indexOf(connection), 1); // 若房间内没有人了,则将房间移除 --可能会有问题 --Written By Copilot if(clientsList.get(roomid).length == 0){ clientsList.delete(roomid); console.log('Delete Room: ' + roomid); } clientsList.get('public').push(connection); // 将client从指定的roomid中移除 -- 可能会有问题 -- Written By Copilot connection.roomid.splice(connection.roomid.indexOf(roomid), 1); console.log("Leave! roomid = " + connection.roomid); } // 获取已加入的房间 function getJoinedRoom(connection){ return connection.roomid } // 广播消息 function broadCastForAll(msg){ clientsList.forEach(Listed => { Listed.forEach(Client => { Client.sendUTF(msg); }); }); }