/** * author: Sand * since: 2016/11/17 */ "use strict"; let log = require("../util/log.js"); let clientCache = require('../models/socket.io/client.cache').clientCache(); let PatientClient = require('./../models/socket.io/patient.client'); let PcDoctorClient = require('./../models/socket.io/pcDoctor.client'); let DoctorClient = require('./../models/socket.io/doctor.client'); let RtcClient = require('../models/socket.io/rtc.client.js'); let Sessions = require('../models/sessions/sessions'); let Users = require('../models/user/users'); let ModelUtil = require('../util/model.util.js'); let pusher = require('../models/push/pusher.js'); let AppClient = require('../models/client/app.client.js'); let sessions = new Sessions(); let users = new Users(); class SocketHandler { constructor(socketServer) { this._socketServer = socketServer; } sleep (time) { return new Promise((resolve) => setTimeout(resolve, time)); } /** * 启用事件监听。 */ start() { let socketServer = this._socketServer; socketServer.sockets.on('connection', function (socket) { log.info('one user connection...'); // 客户端注册 socket.on('login', function (data) { if (!data.userId) { socketServer.sockets.emit('error', {message: 'Missing fields(s): userId.'}); } else { if("pc_doctor"===data.clientType){//新增pc端医生登录 data.userId = "pc_"+data.userId; }else if("pcim_doctor"===data.clientType){//用于pcim 消息通知 data.userId = "pcim_"+data.userId; } if(clientCache.removeByUserId(data.userId)){ log.info("User " + data.userId + " already login"); return; } log.info('User ' + data.userId + ' login'); if(!data.clientType||data.clientType=="patient"){ let patientClient = new PatientClient(socket, socketServer); patientClient.userId = data.userId; patientClient.password = data.password; patientClient.clientType = data.clientType||"patient"; patientClient.sessionId = data.sessionId||""; clientCache.addClient(patientClient); users.login(data.userId, 10, '', ''); socket.emit('ack', {}); }else if("pcim_doctor"===data.clientType){ //用于pcim 消息通知 let pcdoctorClient = new PcDoctorClient(socket, socketServer); pcdoctorClient.userId = data.userId; pcdoctorClient.password = data.password; pcdoctorClient.clientType = data.clientType; pcdoctorClient.sessionId = ""; clientCache.addClient(pcdoctorClient); socket.emit('ack', {}); }else{ let doctorClient = new DoctorClient(socket, socketServer); doctorClient.userId = data.userId; doctorClient.password = data.password; doctorClient.clientType = data.clientType; doctorClient.sessionId = data.sessionId||""; clientCache.addClient(doctorClient); socket.emit('ack', {}); } } }); // 返回userid的socketid socket.on('getSid',function(data){ var clientJson = null; if(!(data instanceof Object)){ clientJson = JSON.parse(data); }else{ clientJson = data; } var userId = clientJson.userId; var rtcClient = clientCache.findById(userId); if(rtcClient === undefined){ socketServer.sockets.emit('error', {message: 'this socket client has not ever connect '}); return; } var result = {'userId':userId,'sid':rtcClient._socket.id}; log.info('request getSid,userid :'+userId); socket.emit('getSid',result); }); // 设置userid的socketid socket.on('setSid',function(data){ var clientJson = null; if(!(data instanceof Object)){ clientJson = JSON.parse(data); }else{ clientJson = data; } var userId = clientJson.userId; let rtcClient = new RtcClient(socket,socketServer); rtcClient.userId = userId; clientCache.addClient(rtcClient); var result = {'userId':userId,'sid':rtcClient._socket.id}; log.info('request setSid,userid :'+userId); socket.emit('setSid',result); }); // 接收客户端消息 /** * 视频消息格式: * var payload = { userId: userId, sid:sid, socket.io 的id targetId: targetUid, type: "offer/answer/hang-up/time-out/canidate", 发起视频/接受视频/(拒绝视频|挂断视频)/超时 sdp: myPeerConnection.localDescription }; */ socket.on('message', function (data) { var payload = null; if(!(data instanceof Object)){ payload = JSON.parse(data); }else{ payload = data; } // 视频聊天消息 if(payload !== undefined && payload.type){ if(payload.fromSid === undefined || payload.fromSid === ''){ socket.emit('error', {error: 'Missing fields(s): sid.',"payload":payload}); return; } switch (payload.type) { case 'video-offer': let title = 'videoCall'; /* var getui = { from:from_userId, fromSid:from_sid, to:to_userId, msgType: "videoCall", };*/ AppClient.getAppStatus(payload.targetId, function (err, userStatus) { if (err) { ModelUtil.logError("Get user app status failed", err); socket.emit('error', {error: 'cannot get ClietnId for targetId:' + payload.targetId,"payload":payload}); return; } pusher.pushToSingleViaAndroid(title, title, payload, userStatus.client_id, userStatus.app_in_bg, function (err, res) { if (err) { ModelUtil.logError("Send notification via Android failed", err); socket.emit('error', {error: 'Send notification via Android failed for targetId:' + payload.targetId,"payload":payload}); } else { log.info("offer Send notification via Android succeed: ", JSON.stringify(res)); } }); }); break; case 'video-answer': var rtcClientSocket = clientCache.findById(payload.targetId); if(rtcClientSocket === undefined){ socket.emit('error',{error: 'cannot find this socket client for userid:'+ payload.targetId + ' when video-answer',"payload":payload}); return } rtcClientSocket._socket.send(payload,function(client){ }); break; case 'candidate': var rtcClientSocket = clientCache.findById(payload.targetId); if(rtcClientSocket === undefined){ socket.emit('error',{error: 'cannot find this socket client for userid:'+ payload.targetId + ' when candidate',"payload":payload}); return } rtcClientSocket._socket.send(payload,function(client){ }); break; case 'hang-up': var rtcClientSocket = clientCache.findById(payload.targetId); if(rtcClientSocket === undefined){ socket.emit('error',{error: 'cannot find this socket client for userid:'+ payload.targetId + ' when hang-up',"payload":payload}); return } rtcClientSocket._socket.send(payload,function(client){ }); case 'time-out': var rtcClientSocket = clientCache.findById(payload.targetId); if(rtcClientSocket === undefined){ socket.emit('error',{error: 'cannot find this socket client for userid:'+ payload.targetId + ' when time-out',"payload":payload}); return } rtcClientSocket._socket.send(payload,function(client){ }); break; } }else{ // 其他类型的消息 log.info('Got message from ' + clientCache.findBySocket(socket).userId); let sessionId = data.session_id; let message = data.message; message.timestamp = new Date(); /*sessions.createSession(sessionId, "Let's talk!", 1, ['504a0bcddb1e4e37a0306b39c51900b5', 'cd92414c-5b06-11e6-8344-fa163e8aee56'], function (err, res) { sessions.saveMessageBySession(sessionId, message); });*/ sessions.saveMessageBySession(sessionId, message); } }); socket.on('error',function(errMsg){ log.info(JSON.stringify(errMsg)); socket.emit(errMsg); }); // 客户端退出 socket.on('logout', function (data) { let client = clientCache.findBySocket(socket); if (client) { log.info('User logout: ' + client.userId); clientCache.removeByUserId(client.userId); } }); // 客户端断开 socket.on('disconnect', function (soc) { let patientClient = clientCache.findBySocket(socket); if (patientClient) { log.info("User disconnect: ", patientClient.userId); clientCache.removeByUserSocket(socket); } }); socket.emit('welcome', {message: 'Welcome to connect IM server, please login.'}); }); } } module.exports = SocketHandler;