| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- let WebSocketServer = require('ws').Server;
- let UUID = require('node-uuid');
- let http = require('http');
- let events = require('events');
- let util = require('util');
- let errorCb = function (rtc) {
- return function (error) {
- if (error) {
- rtc.emit("error", error);
- }
- };
- };
- function SkyRTC() {
- this.sockets = [];
- this.rooms = {};
- // 加入房间
- this.on('__join', function (data, socket) {
- let ids = [],
- i, m,
- room = data.room || "__default",
- curSocket,
- curRoom,
- curHost;
- console.log("房间" + room + "里有" + this.sockets.length + "人");
- var socket_index = this.sockets.indexOf(socket)
- this.sockets[socket_index].role = data.role ? data.role : "host";
- socket.role = data.role ? data.role : "host";
- curRoom = this.rooms[room] = this.rooms[room] || [];
- var guestCount = 0;
- for (i = 0, m = curRoom.length; i < m; i++) {
- curSocket = curRoom[i];
- if (curSocket.role === "guest") {
- guestCount = guestCount + 1;
- }
- }
- console.log("guestCount = " + guestCount);
- if (guestCount >= 3 && data.role === "guest") {
- socket.send(JSON.stringify({
- "eventName": "_peers",
- "data": {
- "connections": [],
- "you": socket.id,
- "yourole": data.role ? data.role : "host",
- "code":-1,
- "message":"通话人数已达上限,无法加入",
- "host":''
- }
- }), errorCb);
- socket.close();
- return;
- }
- for (i = 0, m = curRoom.length; i < m; i++) {
- curSocket = curRoom[i];
- if (curSocket.id === socket.id) {
- curSocket.role = data.role ? data.role : "host";
- continue;
- }
- ids.push(curSocket.id);
- curSocket.send(JSON.stringify({
- "eventName": "_new_peer",
- "data": {
- "socketId": socket.id,
- "role" : data.role ? data.role : "host"
- }
- }), errorCb);
- if (curSocket.role === "host") {
- curHost = curSocket.id;
- }
- }
-
- curRoom.push(socket);
- socket.room = room;
- if (socket.role === "host") {
- curHost = socket.id;
- }
- socket.send(JSON.stringify({
- "eventName": "_peers",
- "data": {
- "connections": ids,
- "you": socket.id,
- "yourole": data.role ? data.role : "host",
- "code":0,
- "message":"成功",
- "host":curHost
- }
- }), errorCb);
- this.emit('new_peer', socket, room);
- //console.log(this.sockets);
- if (socket.role === "host") {
- // 通知后台,梯屏已进入房间
- const options = {
- // hostname: 'elevator.inspuriit.com',
- hostname: '127.0.0.1',
- // port: 80,
- port: 8081,
- path: '/admin/joinroom/callback/' + room,
- method: 'GET',
- };
- const req = http.request(options, (res) => {
- let data = '';
- res.on('data', (chunk) => {
- data += chunk;
- });
- res.on('end', () => {
- console.log(data);
- });
- });
- req.end();
- }
- });
- this.on('__ice_candidate', function (data, socket) {
- var soc = this.getSocket(data.socketId);
- if (soc) {
- soc.send(JSON.stringify({
- "eventName": "_ice_candidate",
- "data": {
- "id": data.id,
- "label": data.label,
- "sdpMLineIndex" :data.label,
- "candidate": data.candidate,
- "socketId": socket.id
- }
- }), errorCb);
- this.emit('ice_candidate', socket, data);
- }
- });
- this.on('__offer', function (data, socket) {
- var soc = this.getSocket(data.socketId);
- if (soc) {
- soc.send(JSON.stringify({
- "eventName": "_offer",
- "data": {
- "sdp": data.sdp,
- "socketId": socket.id
- }
- }), errorCb);
- }
- this.emit('offer', socket, data);
- });
- this.on('__answer', function (data, socket) {
- var soc = this.getSocket(data.socketId);
- if (soc) {
- soc.send(JSON.stringify({
- "eventName": "_answer",
- "data": {
- "sdp": data.sdp,
- "socketId": socket.id
- }
- }), errorCb);
- this.emit('answer', socket, data);
- }
- });
- // 发起邀请
- this.on('__invite', function (data) {
- });
- // 回应数据
- this.on('__ack', function (data) {
- });
- // 状态变更--废弃
- this.on('__status_update', function (data, socket) {
- let ids = [],
- i, m,
- room = data.room || "__default",
- curSocket,
- curRoom,
- curHost;
- console.log("__status_update,房间" + room + "里有" + this.sockets.length + "人");
- curRoom = this.rooms[room] = this.rooms[room] || [];
- for (i = 0, m = curRoom.length; i < m; i++) {
- curSocket = curRoom[i];
- if (curSocket.id === socket.id) {
- continue;
- }
- curSocket.send(JSON.stringify({
- "eventName": "__status_update",
- "data": data
- }), errorCb);
- }
- });
- this.on('__state_response', function (data, socket) {
- let ids = [],
- i, m,
- room = data.room || "__default",
- curSocket,
- curRoom,
- curHost;
- console.log("__state_response,房间" + room + "里有" + this.sockets.length + "人");
- curRoom = this.rooms[room] = this.rooms[room] || [];
- for (i = 0, m = curRoom.length; i < m; i++) {
- curSocket = curRoom[i];
- if (curSocket.id === data.to) {
- curSocket.send(JSON.stringify({
- "eventName": "__state_response",
- "data": data
- }), errorCb);
- }
- }
- //this.emit('new_peer', socket, room);
- });
- // 状态变更--废弃结束
- this.on('__heartbeat', function (data, socket) {
- socket.send(JSON.stringify({
- "eventName": "__heartbeat",
- "data": data
- }), errorCb);
- });
- this.on('__state', function (data, socket) {
- let ids = [],
- i, m,
- room = socket.room || "__default",
- curSocket,
- curRoom,
- curHost;
- console.log("__state," + room + "里有" + this.sockets.length + "人");
- curRoom = this.rooms[room] = this.rooms[room] || [];
- for (i = 0, m = curRoom.length; i < m; i++) {
- curSocket = curRoom[i];
- if (curSocket.id === socket.id) {
- continue;
- }
- console.log("data.to=" + data.to);
- if (!data.to || data.to === curSocket.id) {
- curSocket.send(JSON.stringify({
- "eventName": "__state",
- "data": data
- }), errorCb);
- }
- }
- });
- }
- util.inherits(SkyRTC, events.EventEmitter);
- SkyRTC.prototype.addSocket = function (socket) {
- this.sockets.push(socket);
- };
- SkyRTC.prototype.removeSocket = function (socket) {
- var i = this.sockets.indexOf(socket),
- room = socket.room;
- this.sockets.splice(i, 1);
- if (room) {
- i = this.rooms[room].indexOf(socket);
- this.rooms[room].splice(i, 1);
- if (this.rooms[room].length === 0) {
- delete this.rooms[room];
- }
- if (socket.role === "host") {
- // 通知后台,梯屏已退出房间
- const options = {
- // hostname: 'elevator.inspuriit.com',
- hostname: '127.0.0.1',
- // port: 80,
- port: 8081,
- path: '/admin/exitroom/callback/' + room,
- method: 'GET',
- };
- const req = http.request(options, (res) => {
- let data = '';
- res.on('data', (chunk) => {
- data += chunk;
- });
- res.on('end', () => {
- console.log(data);
- });
- });
- req.end();
- }
- }
- };
- SkyRTC.prototype.broadcast = function (data, errorCb) {
- var i;
- for (i = this.sockets.length; i--;) {
- this.sockets[i].send(data, errorCb);
- }
- };
- SkyRTC.prototype.broadcastInRoom = function (room, data, errorCb) {
- var curRoom = this.rooms[room], i;
- if (curRoom) {
- for (i = curRoom.length; i--;) {
- curRoom[i].send(data, errorCb);
- }
- }
- };
- SkyRTC.prototype.getRooms = function () {
- let rooms = [],
- room;
- for (room in this.rooms) rooms.push(room);
- return rooms;
- };
- SkyRTC.prototype.getSocket = function (socketId) {
- let i, curSocket;
- if (!this.sockets) {
- return;
- }
- for (i = this.sockets.length; i--;) {
- curSocket = this.sockets[i];
- if (socketId === curSocket.id) {
- return curSocket;
- }
- }
- };
- function noop() {}
- function heartbeat() {
- console.log('heartbeat, socketid=' + this.id)
- this.isAlive = true;
- }
- SkyRTC.prototype.init = function (socket) {
- let that = this;
- socket.id = UUID.v4();
- socket.isAlive = true;
- socket.on('pong', heartbeat);
- const interval = setInterval(function ping() {
- if (socket.isAlive === false) {
- console.log('timeout, socketid=' + socket.id)
- return socket.close();
- }
- socket.isAlive = false;
- socket.ping(noop);
- }, 10000);
- // console.log(socket);
- that.addSocket(socket);
- //为新连接绑定事件处理器
- socket.on('message', function (data) {
- console.log(data);
- let json = JSON.parse(data);
- if (json.eventName) {
- that.emit(json.eventName, json.data, socket);
- } else {
- that.emit("socket_message", socket, data);
- }
- });
- //连接关闭后从SkyRTC实例中移除连接,并通知其他连接
- socket.on('close', function () {
- clearInterval(interval);
- let i, m,
- room = socket.room,
- curRoom;
- if (room) {
- curRoom = that.rooms[room];
- for (i = curRoom.length; i--;) {
- if (curRoom[i].id === socket.id) {
- continue;
- }
- curRoom[i].send(JSON.stringify({
- "eventName": "_remove_peer",
- "data": {
- "socketId": socket.id,
- "role": socket.role
- }
- }), errorCb);
- console.log("发送到" + curRoom[i].id + " -> " + JSON.stringify({
- "eventName": "_remove_peer",
- "data": {
- "socketId": socket.id,
- "role": socket.role
- }
- }));
- }
- }
- that.removeSocket(socket);
- that.emit('remove_peer', socket.id, that);
- console.log("房间" + room + "里还剩下" + that.sockets.length + "人");
- });
- that.emit('new_connect', socket);
- };
- module.exports.listen = function (server) {
- let SkyRTCServer;
- if (typeof server === 'number') {
- SkyRTCServer = new WebSocketServer({
- port: server
- });
- } else {
- SkyRTCServer = new WebSocketServer({
- server: server
- });
- }
- SkyRTCServer.rtc = new SkyRTC();
- errorCb = errorCb(SkyRTCServer.rtc);
- SkyRTCServer.on('connection', function (socket) {
- this.rtc.init(socket);
- });
- return SkyRTCServer;
- };
|