socket.handler.js 22 KB

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