SkyRTC.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. let WebSocketServer = require('ws').Server;
  2. let UUID = require('node-uuid');
  3. let http = require('http');
  4. let events = require('events');
  5. let util = require('util');
  6. let errorCb = function (rtc) {
  7. return function (error) {
  8. if (error) {
  9. rtc.emit("error", error);
  10. }
  11. };
  12. };
  13. function SkyRTC() {
  14. this.sockets = [];
  15. this.rooms = {};
  16. // 加入房间
  17. this.on('__join', function (data, socket) {
  18. let ids = [],
  19. i, m,
  20. room = data.room || "__default",
  21. curSocket,
  22. curRoom,
  23. curHost;
  24. console.log("房间" + room + "里有" + this.sockets.length + "人");
  25. var socket_index = this.sockets.indexOf(socket)
  26. this.sockets[socket_index].role = data.role ? data.role : "host";
  27. socket.role = data.role ? data.role : "host";
  28. curRoom = this.rooms[room] = this.rooms[room] || [];
  29. var guestCount = 0;
  30. for (i = 0, m = curRoom.length; i < m; i++) {
  31. curSocket = curRoom[i];
  32. if (curSocket.role === "guest") {
  33. guestCount = guestCount + 1;
  34. }
  35. }
  36. console.log("guestCount = " + guestCount);
  37. if (guestCount >= 3 && data.role === "guest") {
  38. socket.send(JSON.stringify({
  39. "eventName": "_peers",
  40. "data": {
  41. "connections": [],
  42. "you": socket.id,
  43. "yourole": data.role ? data.role : "host",
  44. "code":-1,
  45. "message":"通话人数已达上限,无法加入",
  46. "host":''
  47. }
  48. }), errorCb);
  49. socket.close();
  50. return;
  51. }
  52. for (i = 0, m = curRoom.length; i < m; i++) {
  53. curSocket = curRoom[i];
  54. if (curSocket.id === socket.id) {
  55. curSocket.role = data.role ? data.role : "host";
  56. continue;
  57. }
  58. ids.push(curSocket.id);
  59. curSocket.send(JSON.stringify({
  60. "eventName": "_new_peer",
  61. "data": {
  62. "socketId": socket.id,
  63. "role" : data.role ? data.role : "host"
  64. }
  65. }), errorCb);
  66. if (curSocket.role === "host") {
  67. curHost = curSocket.id;
  68. }
  69. }
  70. curRoom.push(socket);
  71. socket.room = room;
  72. if (socket.role === "host") {
  73. curHost = socket.id;
  74. }
  75. socket.send(JSON.stringify({
  76. "eventName": "_peers",
  77. "data": {
  78. "connections": ids,
  79. "you": socket.id,
  80. "yourole": data.role ? data.role : "host",
  81. "code":0,
  82. "message":"成功",
  83. "host":curHost
  84. }
  85. }), errorCb);
  86. this.emit('new_peer', socket, room);
  87. //console.log(this.sockets);
  88. if (socket.role === "host") {
  89. // 通知后台,梯屏已进入房间
  90. const options = {
  91. // hostname: 'elevator.inspuriit.com',
  92. hostname: '127.0.0.1',
  93. // port: 80,
  94. port: 8081,
  95. path: '/admin/joinroom/callback/' + room,
  96. method: 'GET',
  97. };
  98. const req = http.request(options, (res) => {
  99. let data = '';
  100. res.on('data', (chunk) => {
  101. data += chunk;
  102. });
  103. res.on('end', () => {
  104. console.log(data);
  105. });
  106. });
  107. req.end();
  108. }
  109. });
  110. this.on('__ice_candidate', function (data, socket) {
  111. var soc = this.getSocket(data.socketId);
  112. if (soc) {
  113. soc.send(JSON.stringify({
  114. "eventName": "_ice_candidate",
  115. "data": {
  116. "id": data.id,
  117. "label": data.label,
  118. "sdpMLineIndex" :data.label,
  119. "candidate": data.candidate,
  120. "socketId": socket.id
  121. }
  122. }), errorCb);
  123. this.emit('ice_candidate', socket, data);
  124. }
  125. });
  126. this.on('__offer', function (data, socket) {
  127. var soc = this.getSocket(data.socketId);
  128. if (soc) {
  129. soc.send(JSON.stringify({
  130. "eventName": "_offer",
  131. "data": {
  132. "sdp": data.sdp,
  133. "socketId": socket.id
  134. }
  135. }), errorCb);
  136. }
  137. this.emit('offer', socket, data);
  138. });
  139. this.on('__answer', function (data, socket) {
  140. var soc = this.getSocket(data.socketId);
  141. if (soc) {
  142. soc.send(JSON.stringify({
  143. "eventName": "_answer",
  144. "data": {
  145. "sdp": data.sdp,
  146. "socketId": socket.id
  147. }
  148. }), errorCb);
  149. this.emit('answer', socket, data);
  150. }
  151. });
  152. // 发起邀请
  153. this.on('__invite', function (data) {
  154. });
  155. // 回应数据
  156. this.on('__ack', function (data) {
  157. });
  158. // 状态变更--废弃
  159. this.on('__status_update', function (data, socket) {
  160. let ids = [],
  161. i, m,
  162. room = data.room || "__default",
  163. curSocket,
  164. curRoom,
  165. curHost;
  166. console.log("__status_update,房间" + room + "里有" + this.sockets.length + "人");
  167. curRoom = this.rooms[room] = this.rooms[room] || [];
  168. for (i = 0, m = curRoom.length; i < m; i++) {
  169. curSocket = curRoom[i];
  170. if (curSocket.id === socket.id) {
  171. continue;
  172. }
  173. curSocket.send(JSON.stringify({
  174. "eventName": "__status_update",
  175. "data": data
  176. }), errorCb);
  177. }
  178. });
  179. this.on('__state_response', function (data, socket) {
  180. let ids = [],
  181. i, m,
  182. room = data.room || "__default",
  183. curSocket,
  184. curRoom,
  185. curHost;
  186. console.log("__state_response,房间" + room + "里有" + this.sockets.length + "人");
  187. curRoom = this.rooms[room] = this.rooms[room] || [];
  188. for (i = 0, m = curRoom.length; i < m; i++) {
  189. curSocket = curRoom[i];
  190. if (curSocket.id === data.to) {
  191. curSocket.send(JSON.stringify({
  192. "eventName": "__state_response",
  193. "data": data
  194. }), errorCb);
  195. }
  196. }
  197. //this.emit('new_peer', socket, room);
  198. });
  199. // 状态变更--废弃结束
  200. this.on('__heartbeat', function (data, socket) {
  201. socket.send(JSON.stringify({
  202. "eventName": "__heartbeat",
  203. "data": data
  204. }), errorCb);
  205. });
  206. this.on('__state', function (data, socket) {
  207. let ids = [],
  208. i, m,
  209. room = socket.room || "__default",
  210. curSocket,
  211. curRoom,
  212. curHost;
  213. console.log("__state," + room + "里有" + this.sockets.length + "人");
  214. curRoom = this.rooms[room] = this.rooms[room] || [];
  215. for (i = 0, m = curRoom.length; i < m; i++) {
  216. curSocket = curRoom[i];
  217. if (curSocket.id === socket.id) {
  218. continue;
  219. }
  220. console.log("data.to=" + data.to);
  221. if (!data.to || data.to === curSocket.id) {
  222. curSocket.send(JSON.stringify({
  223. "eventName": "__state",
  224. "data": data
  225. }), errorCb);
  226. }
  227. }
  228. });
  229. }
  230. util.inherits(SkyRTC, events.EventEmitter);
  231. SkyRTC.prototype.addSocket = function (socket) {
  232. this.sockets.push(socket);
  233. };
  234. SkyRTC.prototype.removeSocket = function (socket) {
  235. var i = this.sockets.indexOf(socket),
  236. room = socket.room;
  237. this.sockets.splice(i, 1);
  238. if (room) {
  239. i = this.rooms[room].indexOf(socket);
  240. this.rooms[room].splice(i, 1);
  241. if (this.rooms[room].length === 0) {
  242. delete this.rooms[room];
  243. }
  244. if (socket.role === "host") {
  245. // 通知后台,梯屏已退出房间
  246. const options = {
  247. // hostname: 'elevator.inspuriit.com',
  248. hostname: '127.0.0.1',
  249. // port: 80,
  250. port: 8081,
  251. path: '/admin/exitroom/callback/' + room,
  252. method: 'GET',
  253. };
  254. const req = http.request(options, (res) => {
  255. let data = '';
  256. res.on('data', (chunk) => {
  257. data += chunk;
  258. });
  259. res.on('end', () => {
  260. console.log(data);
  261. });
  262. });
  263. req.end();
  264. }
  265. }
  266. };
  267. SkyRTC.prototype.broadcast = function (data, errorCb) {
  268. var i;
  269. for (i = this.sockets.length; i--;) {
  270. this.sockets[i].send(data, errorCb);
  271. }
  272. };
  273. SkyRTC.prototype.broadcastInRoom = function (room, data, errorCb) {
  274. var curRoom = this.rooms[room], i;
  275. if (curRoom) {
  276. for (i = curRoom.length; i--;) {
  277. curRoom[i].send(data, errorCb);
  278. }
  279. }
  280. };
  281. SkyRTC.prototype.getRooms = function () {
  282. let rooms = [],
  283. room;
  284. for (room in this.rooms) rooms.push(room);
  285. return rooms;
  286. };
  287. SkyRTC.prototype.getSocket = function (socketId) {
  288. let i, curSocket;
  289. if (!this.sockets) {
  290. return;
  291. }
  292. for (i = this.sockets.length; i--;) {
  293. curSocket = this.sockets[i];
  294. if (socketId === curSocket.id) {
  295. return curSocket;
  296. }
  297. }
  298. };
  299. function noop() {}
  300. function heartbeat() {
  301. console.log('heartbeat, socketid=' + this.id)
  302. this.isAlive = true;
  303. }
  304. SkyRTC.prototype.init = function (socket) {
  305. let that = this;
  306. socket.id = UUID.v4();
  307. socket.isAlive = true;
  308. socket.on('pong', heartbeat);
  309. const interval = setInterval(function ping() {
  310. if (socket.isAlive === false) {
  311. console.log('timeout, socketid=' + socket.id)
  312. return socket.close();
  313. }
  314. socket.isAlive = false;
  315. socket.ping(noop);
  316. }, 10000);
  317. // console.log(socket);
  318. that.addSocket(socket);
  319. //为新连接绑定事件处理器
  320. socket.on('message', function (data) {
  321. console.log(data);
  322. let json = JSON.parse(data);
  323. if (json.eventName) {
  324. that.emit(json.eventName, json.data, socket);
  325. } else {
  326. that.emit("socket_message", socket, data);
  327. }
  328. });
  329. //连接关闭后从SkyRTC实例中移除连接,并通知其他连接
  330. socket.on('close', function () {
  331. clearInterval(interval);
  332. let i, m,
  333. room = socket.room,
  334. curRoom;
  335. if (room) {
  336. curRoom = that.rooms[room];
  337. for (i = curRoom.length; i--;) {
  338. if (curRoom[i].id === socket.id) {
  339. continue;
  340. }
  341. curRoom[i].send(JSON.stringify({
  342. "eventName": "_remove_peer",
  343. "data": {
  344. "socketId": socket.id,
  345. "role": socket.role
  346. }
  347. }), errorCb);
  348. console.log("发送到" + curRoom[i].id + " -> " + JSON.stringify({
  349. "eventName": "_remove_peer",
  350. "data": {
  351. "socketId": socket.id,
  352. "role": socket.role
  353. }
  354. }));
  355. }
  356. }
  357. that.removeSocket(socket);
  358. that.emit('remove_peer', socket.id, that);
  359. console.log("房间" + room + "里还剩下" + that.sockets.length + "人");
  360. });
  361. that.emit('new_connect', socket);
  362. };
  363. module.exports.listen = function (server) {
  364. let SkyRTCServer;
  365. if (typeof server === 'number') {
  366. SkyRTCServer = new WebSocketServer({
  367. port: server
  368. });
  369. } else {
  370. SkyRTCServer = new WebSocketServer({
  371. server: server
  372. });
  373. }
  374. SkyRTCServer.rtc = new SkyRTC();
  375. errorCb = errorCb(SkyRTCServer.rtc);
  376. SkyRTCServer.on('connection', function (socket) {
  377. this.rtc.init(socket);
  378. });
  379. return SkyRTCServer;
  380. };