socket.handler.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /**
  2. * author: Sand
  3. * since: 2016/11/17
  4. */
  5. "use strict";
  6. let log = require("../util/log.js");
  7. let clientCache = require('../models/socket.io/client.cache').clientCache();
  8. let PatientClient = require('./../models/socket.io/patient.client');
  9. let PcPatientClient = require('./../models/socket.io/pcPatient.client');
  10. let PcDoctorClient = require('./../models/socket.io/pcDoctor.client');
  11. let DoctorClient = require('./../models/socket.io/doctor.client');
  12. let RtcClient = require('../models/socket.io/rtc.client.js');
  13. let Sessions = require('../models/sessions/sessions');
  14. let Users = require('../models/user/users');
  15. let ModelUtil = require('../util/model.util.js');
  16. let pusher = require('../models/push/pusher.js');
  17. let AppClient = require('../models/client/app.client.js');
  18. let Participants = require('../models/sessions/participants');
  19. let sessions = new Sessions();
  20. let users = new Users();
  21. class SocketHandler {
  22. constructor(socketServer) {
  23. this._socketServer = socketServer;
  24. }
  25. sleep (time) {
  26. return new Promise((resolve) => setTimeout(resolve, time));
  27. }
  28. /**
  29. * 启用事件监听。
  30. */
  31. start() {
  32. let socketServer = this._socketServer;
  33. socketServer.sockets.on('connection', function (socket) {
  34. log.info('one user connection...');
  35. // 客户端注册
  36. socket.on('login', function (data) {
  37. if (!data.userId) {
  38. socketServer.sockets.emit('error', {message: 'Missing fields(s): userId.'});
  39. } else {
  40. let mdt_login_tag = data.SYSTEM_TYPE;
  41. //MDT 托盘登陆
  42. if(mdt_login_tag && "MDT" == mdt_login_tag){
  43. //传入手机号,转换成医生CODE
  44. sessions.conversionAarticipant(data.userId, (doctorid) => {
  45. data.userId = "pcim_"+doctorid;
  46. if(clientCache.removeByUserId(data.userId)){
  47. log.info("User " + data.userId + " already loginMDT");
  48. return;
  49. }
  50. log.info('User ' + data.userId + ' loginMDT');
  51. // if("pcim_doctor"===data.clientType){
  52. //用于pcim 消息通知
  53. let pcdoctorClient = new PcDoctorClient(socket, socketServer);
  54. pcdoctorClient.userId = data.userId;
  55. pcdoctorClient.password = data.password;
  56. pcdoctorClient.clientType = data.clientType;
  57. pcdoctorClient.sessionId = "";
  58. clientCache.addClient(pcdoctorClient);
  59. socket.emit('ack', {});
  60. });
  61. }else{
  62. //原始登陆者ID
  63. let original_login_userid = data.userId;
  64. if("pc_doctor"===data.clientType){//新增pc端医生登录
  65. data.userId = "pc_"+data.userId;
  66. }else if("pc_doctor_system"===data.clientType){//新增pc端医生外层-登录类型-20191012-huangnwenjie
  67. data.userId= "pc_system_"+data.userId;
  68. // }else if("pcim_doctor"===data.clientType){//用于pcim 消息通知 MDT-登陆类型已迁移到上面的分支-20191012-huangnwenjie
  69. // data.userId = "pcim_"+data.userId;
  70. }else if("pc_patient"===data.clientType){//新增居民PC登陆类型
  71. data.userId= "pcpatient_"+data.userId;
  72. }else if("pc_patient_system"===data.clientType){//新增居民PC外层-登陆类型-20191012-huangnwenjie
  73. data.userId= "pcpatient_system_"+data.userId;
  74. }else if("patient_system"===data.clientType){//新增居民微信端外层-登陆类型-20191012-huangnwenjie
  75. data.userId= "patient_system_"+data.userId;
  76. }else if("doctor_system"===data.clientType){//新增医生APP外层-登陆类型-20191012-huangnwenjie
  77. data.userId= "doctor_system_"+data.userId;
  78. }
  79. if(clientCache.removeByUserId(data.userId)){
  80. log.info("User " + data.userId + " already login");
  81. return;
  82. }
  83. log.info('User ' + data.userId + ' login');
  84. if(!data.clientType||data.clientType=="patient"||data.clientType=="patient_system"){//新增居民微信端外层-登陆类型-20191012-huangnwenjie
  85. let patientClient = new PatientClient(socket, socketServer);
  86. patientClient.userId = data.userId;
  87. patientClient.password = data.password;
  88. patientClient.clientType = data.clientType||"patient";
  89. patientClient.sessionId = data.sessionId||"";
  90. clientCache.addClient(patientClient);
  91. users.login(data.userId, 10, '', '');
  92. //修改居民在线状态
  93. let participants = new Participants();
  94. participants.changUserRedisLoginStatus(original_login_userid,data.clientType,1,patientClient.sessionId);
  95. socket.emit('ack', {});
  96. }else if("pc_patient"===data.clientType || "pc_patient_system"===data.clientType){////新增居民PC外层-登陆类型-20191012-huangnwenjie
  97. //用于pcpatient 消息通知
  98. let pcpatientClient = new PcPatientClient(socket, socketServer);
  99. pcpatientClient.userId = data.userId;
  100. pcpatientClient.password = data.password;
  101. pcpatientClient.clientType = data.clientType;
  102. pcpatientClient.sessionId = data.sessionId||"";
  103. clientCache.addClient(pcpatientClient);
  104. users.login(data.userId, 10, '', '');
  105. //修改居民在线状态
  106. let participants = new Participants();
  107. participants.changUserRedisLoginStatus(original_login_userid,data.clientType,1,pcpatientClient.sessionId);
  108. socket.emit('ack', {});
  109. //MDT 登陆类型已迁移到上面的分支-20191012-huangnwenjie
  110. // }else if("pcim_doctor"===data.clientType){ 登
  111. // //用于pcim 消息通知
  112. // let pcdoctorClient = new PcDoctorClient(socket, socketServer);
  113. // pcdoctorClient.userId = data.userId;
  114. // pcdoctorClient.password = data.password;
  115. // pcdoctorClient.clientType = data.clientType;
  116. // pcdoctorClient.sessionId = "";
  117. // clientCache.addClient(pcdoctorClient);
  118. // socket.emit('ack', {});
  119. }else{
  120. let doctorClient = new DoctorClient(socket, socketServer);
  121. doctorClient.userId = data.userId;
  122. doctorClient.password = data.password;
  123. doctorClient.clientType = data.clientType;
  124. doctorClient.sessionId = data.sessionId||"";
  125. clientCache.addClient(doctorClient);
  126. //修改医生在线状态
  127. let participants = new Participants();
  128. participants.changUserRedisLoginStatus(original_login_userid,data.clientType,1,doctorClient.sessionId);
  129. socket.emit('ack', {});
  130. }
  131. }
  132. }
  133. });
  134. // 客户端注册
  135. socket.on('loginMDT', function (data) {
  136. if (!data.userId) {
  137. socketServer.sockets.emit('error', {message: 'Missing fields(s): userId.'});
  138. } else {
  139. sessions.conversionAarticipant(j, (doctorid) => {
  140. data.userId = "pcim_"+doctorid;
  141. if(clientCache.removeByUserId(data.userId)){
  142. log.info("User " + data.userId + " already loginMDT");
  143. return;
  144. }
  145. log.info('User ' + data.userId + ' loginMDT');
  146. // if("pcim_doctor"===data.clientType){
  147. //用于pcim 消息通知
  148. let pcdoctorClient = new PcDoctorClient(socket, socketServer);
  149. pcdoctorClient.userId = data.userId;
  150. pcdoctorClient.password = data.password;
  151. pcdoctorClient.clientType = data.clientType;
  152. pcdoctorClient.sessionId = "";
  153. clientCache.addClient(pcdoctorClient);
  154. socket.emit('ack', {});
  155. // }
  156. });
  157. }
  158. });
  159. //视频聊天
  160. // 返回userid的socketid
  161. socket.on('getSid',function(data){
  162. var clientJson = null;
  163. if(!(data instanceof Object)){
  164. clientJson = JSON.parse(data);
  165. }else{
  166. clientJson = data;
  167. }
  168. var userId = clientJson.userId;
  169. var rtcClient = clientCache.findById(userId);
  170. if(rtcClient === undefined){
  171. socketServer.sockets.emit('error', {message: 'this socket client has not ever connect '});
  172. return;
  173. }
  174. var result = {'userId':userId,'sid':rtcClient._socket.id};
  175. log.info('request getSid,userid :'+userId);
  176. socket.emit('getSid',result);
  177. });
  178. //视频聊天
  179. // 设置userid的socketid
  180. socket.on('setSid',function(data){
  181. var clientJson = null;
  182. if(!(data instanceof Object)){
  183. clientJson = JSON.parse(data);
  184. }else{
  185. clientJson = data;
  186. }
  187. var userId = clientJson.userId;
  188. let rtcClient = new RtcClient(socket,socketServer);
  189. rtcClient.userId = userId;
  190. clientCache.addClient(rtcClient);
  191. var result = {'userId':userId,'sid':rtcClient._socket.id};
  192. log.info('request setSid,userid :'+userId);
  193. socket.emit('setSid',result);
  194. });
  195. // 接收客户端消息
  196. /**
  197. * 视频消息格式:
  198. * var payload = {
  199. userId: userId,
  200. sid:sid, socket.io 的id
  201. targetId: targetUid,
  202. type: "offer/answer/hang-up/time-out/canidate", 发起视频/接受视频/(拒绝视频|挂断视频)/超时
  203. sdp: myPeerConnection.localDescription
  204. };
  205. */
  206. socket.on('message', function (data) {
  207. var payload = null;
  208. if(!(data instanceof Object)){
  209. payload = JSON.parse(data);
  210. }else{
  211. payload = data;
  212. }
  213. // 视频聊天消息
  214. if(payload !== undefined && payload.type){
  215. if(payload.fromSid === undefined || payload.fromSid === ''){
  216. socket.emit('error', {error: 'Missing fields(s): sid.',"payload":payload});
  217. return;
  218. }
  219. switch (payload.type) {
  220. case 'video-offer':
  221. let title = 'videoCall';
  222. /* var getui = {
  223. from:from_userId,
  224. fromSid:from_sid,
  225. to:to_userId,
  226. msgType: "videoCall",
  227. };*/
  228. AppClient.getAppStatus(payload.targetId, function (err, userStatus) {
  229. if (err) {
  230. ModelUtil.logError("Get user app status failed", err);
  231. socket.emit('error', {error: 'cannot get ClietnId for targetId:' + payload.targetId,"payload":payload});
  232. return;
  233. }
  234. pusher.pushToSingleViaAndroid(title, title, payload, userStatus.client_id, userStatus.app_in_bg, function (err, res) {
  235. if (err) {
  236. ModelUtil.logError("Send notification via Android failed", err);
  237. socket.emit('error', {error: 'Send notification via Android failed for targetId:' + payload.targetId,"payload":payload});
  238. } else {
  239. log.info("offer Send notification via Android succeed: ", JSON.stringify(res));
  240. }
  241. });
  242. });
  243. break;
  244. case 'video-answer':
  245. var rtcClientSocket = clientCache.findById(payload.targetId);
  246. if(rtcClientSocket === undefined){
  247. socket.emit('error',{error: 'cannot find this socket client for userid:'+ payload.targetId + ' when video-answer',"payload":payload});
  248. return
  249. }
  250. rtcClientSocket._socket.send(payload,function(client){
  251. });
  252. break;
  253. case 'candidate':
  254. var rtcClientSocket = clientCache.findById(payload.targetId);
  255. if(rtcClientSocket === undefined){
  256. socket.emit('error',{error: 'cannot find this socket client for userid:'+ payload.targetId + ' when candidate',"payload":payload});
  257. return
  258. }
  259. rtcClientSocket._socket.send(payload,function(client){
  260. });
  261. break;
  262. case 'hang-up':
  263. var rtcClientSocket = clientCache.findById(payload.targetId);
  264. if(rtcClientSocket === undefined){
  265. socket.emit('error',{error: 'cannot find this socket client for userid:'+ payload.targetId + ' when hang-up',"payload":payload});
  266. return
  267. }
  268. rtcClientSocket._socket.send(payload,function(client){
  269. });
  270. case 'time-out':
  271. var rtcClientSocket = clientCache.findById(payload.targetId);
  272. if(rtcClientSocket === undefined){
  273. socket.emit('error',{error: 'cannot find this socket client for userid:'+ payload.targetId + ' when time-out',"payload":payload});
  274. return
  275. }
  276. rtcClientSocket._socket.send(payload,function(client){
  277. });
  278. break;
  279. }
  280. }else{
  281. // 其他类型的消息
  282. log.info('Got message from ' + clientCache.findBySocket(socket).userId);
  283. let sessionId = data.session_id;
  284. let message = data.message;
  285. message.timestamp = new Date();
  286. /*sessions.createSession(sessionId, "Let's talk!", 1, ['504a0bcddb1e4e37a0306b39c51900b5', 'cd92414c-5b06-11e6-8344-fa163e8aee56'], function (err, res) {
  287. sessions.saveMessageBySession(sessionId, message);
  288. });*/
  289. sessions.saveMessageBySession(sessionId, message);
  290. }
  291. });
  292. socket.on('error',function(errMsg){
  293. let client = clientCache.findBySocket(socket);
  294. if (client) {
  295. //修改居民在线状态
  296. // users.changUserRedisLoginStatus(original_login_userid,client.clientType,0);
  297. //通知会话的其他成员离线消息
  298. if(client.sessionId != "system"){
  299. let participants = new Participants();
  300. participants.emitSessionUsers(client.sessionId,client.userId,"offline");
  301. }
  302. }
  303. log.info(JSON.stringify(errMsg));
  304. socket.emit(errMsg);
  305. });
  306. // 客户端退出
  307. socket.on('logout', function (data) {
  308. let client = clientCache.findBySocket(socket);
  309. if (client) {
  310. //修改居民在线状态
  311. // users.changUserRedisLoginStatus(original_login_userid,client.clientType,0);
  312. //通知会话的其他成员离线消息
  313. if(client.sessionId != "system"){
  314. let participants = new Participants();
  315. participants.emitSessionUsers(client.sessionId,client.userId,"offline");
  316. }
  317. log.info('User logout: ' + client.userId);
  318. clientCache.removeByUserId(client.userId);
  319. }
  320. });
  321. // 客户端断开
  322. socket.on('disconnect', function (soc) {
  323. let patientClient = clientCache.findBySocket(socket);
  324. if (patientClient) {
  325. //修改居民在线状态
  326. // users.changUserRedisLoginStatus(original_login_userid,client.clientType,0);
  327. //通知会话的其他成员离线消息
  328. if(patientClient.sessionId != "system"){
  329. let participants = new Participants();
  330. participants.emitSessionUsers(patientClient.sessionId,patientClient.userId,"offline");
  331. }
  332. log.info("User disconnect: ", patientClient.userId);
  333. clientCache.removeByUserSocket(socket);
  334. }
  335. });
  336. socket.emit('welcome', {message: 'Welcome to connect IM server, please login.'});
  337. });
  338. }
  339. }
  340. module.exports = SocketHandler;