app.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. TODO:
  3. * 在指定的房间内广播数据 BroadcastInRoom(roomid, msg)
  4. * 探索出能解决将同一roomid的客户加入房间的问题的方法
  5. FIXME:
  6. * 暂无待修正
  7. XXX:
  8. * 房间功能
  9. */
  10. // 导入模块
  11. var WebsocketServer = require('websocket').server;
  12. var http = require('http');
  13. const { connection } = require('websocket');
  14. //const { client } = require('websocket');
  15. // 创建http服务器(用于承载WS)
  16. var server = http.createServer();
  17. // 端口设置端口
  18. const PORT = 3000 || process.env.PORT
  19. // 客户端列表
  20. var clientsList = new Map();
  21. // 初始化public,这将是未指定房间默认加入的房间
  22. clientsList.set('public',[]);
  23. // http绑定端口
  24. server.listen(PORT, () => {
  25. console.log("Server running on http://localhost:" + PORT);
  26. });
  27. // 在http服务器上运行WS服务器
  28. var wsServer = new WebsocketServer({httpServer:server});
  29. // 当客户端连入时
  30. wsServer.on('request', (websocketRequest) => {
  31. var connection = websocketRequest.accept(null, 'accepted-origin');
  32. //将客户端插入终端列表
  33. clientsList.get('public').push(connection);
  34. console.log('A client connected');
  35. // 当收到消息时
  36. connection.on('message', (msg) => {
  37. // 判断消息类型
  38. if(msg.type == 'utf8'){
  39. // 过滤非法数据
  40. try {
  41. /*
  42. 定义的数据传送格式规范(JSON):
  43. tag:数据标签
  44. msg:数据内容
  45. opt:Boolean,确认是否为执行操作,操作tag与用户传输的tag重合。
  46. args: opt参数
  47. */
  48. // 解析数据
  49. cd = JSON.parse(msg.utf8Data);
  50. // 开发中,将客户端加入某个房间
  51. if(cd.tag == 'setRoom' && cd.opt == true){
  52. joinToRoom(cd.msg, connection)
  53. }
  54. // 房间内群发
  55. if(cd.tag == 'roomcast' && cd.opt == true && cd.arg != undefined){
  56. console.log('Cast!')
  57. BroadcastInRoom(cd.arg.roomid, 'cast', cd.msg);
  58. }else if(cd.opt == true && (cd.arg == undefined || cd.arg == "")){
  59. // 无参数提示
  60. console.log('Cannot GET arg');
  61. }else{
  62. console.log('Unknown ERROR');
  63. }
  64. // 常规消息将对所有
  65. if(cd.opt == null || cd.opt == false){
  66. // clientsList.forEach(element => {
  67. // element.sendUTF(cd.msg);
  68. // });
  69. broadCastForAll(cd.msg)
  70. }
  71. console.log(cd);
  72. } catch (error) {
  73. console.log(error);
  74. console.error('Illegal Data');
  75. }
  76. }else{
  77. console.log(msg);
  78. }
  79. });
  80. connection.on('close', (reasonCode, description) => {
  81. console.log('A client disconnected');
  82. });
  83. })
  84. // 房间内消息广播
  85. function BroadcastInRoom(roomid, tag, msg){
  86. // for(var i = 0; i < clientsList.length; i++){
  87. // if(clientsList[i].roomid == roomid){
  88. // clientsList[i].send(JSON.stringify({'tag': tag, 'msg': msg}));
  89. // }
  90. // }
  91. clientsList.forEach(element => {
  92. if(element.roomid == roomid){
  93. element.send(JSON.stringify({'tag': tag, 'msg': msg}));
  94. }
  95. });
  96. console.log("CAST!!!!")
  97. }
  98. function joinToRoom(roomid, connection){
  99. // 如果客户端对象没有设置过roomid属性则增设
  100. if(connection.roomid == undefined){
  101. connection.roomid = [];
  102. //connection.roomid = cd.msg;
  103. connection.roomid.push(roomid)
  104. }
  105. // 如果未创建过该房间,则创建
  106. if(!clientsList.has(roomid)){
  107. clientsList.set(roomid,[]);
  108. console.log('Create Room: ' + roomid);
  109. }
  110. // 将client加入到指定roomid的list
  111. clientsList.get(roomid).push(connection);
  112. // 将传进来的roomid属性写入
  113. connection.roomid.push(cd.msg);
  114. console.log("Set! roomid = " + connection.roomid);
  115. }
  116. // 离开房间
  117. function leaveFromRoom(roomid, connection){
  118. // 如果客户端对象没有设置过roomid属性则返回错误信息
  119. if(connection.roomid == undefined){
  120. return false;
  121. }
  122. // 将client从ClientsList指定的房间roomid中移除并移入默认的public --可能会有问题 --Written By Copilot
  123. clientsList.get(roomid).splice(clientsList.get(roomid).indexOf(connection), 1);
  124. // 若房间内没有人了,则将房间移除 --可能会有问题 --Written By Copilot
  125. if(clientsList.get(roomid).length == 0){
  126. clientsList.delete(roomid);
  127. console.log('Delete Room: ' + roomid);
  128. }
  129. clientsList.get('public').push(connection);
  130. // 将client从指定的roomid中移除 -- 可能会有问题 -- Written By Copilot
  131. connection.roomid.splice(connection.roomid.indexOf(roomid), 1);
  132. console.log("Leave! roomid = " + connection.roomid);
  133. }
  134. // 获取已加入的房间
  135. function getJoinedRoom(connection){
  136. return connection.roomid
  137. }
  138. // 广播消息
  139. function broadCastForAll(msg){
  140. clientsList.forEach(Listed => {
  141. Listed.forEach(Client => {
  142. Client.sendUTF(msg);
  143. });
  144. });
  145. }