httpRoomMgr.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /**
  2. * 房间管理http接口
  3. */
  4. 'use strict';
  5. var F = require('../common/function');
  6. var C = require('../config/index');
  7. var _ = require('underscore');
  8. _.str = require('underscore.string');
  9. _.v = require('validator');
  10. var co = require('co');
  11. module.exports = function (app) {
  12. var mgr_map = app.common_mgr.mgr_map;
  13. var http_app = app.app;
  14. /**
  15. * 4.4.http:创建聊天室接口(Java→IM)
  16. */
  17. http_app.regRequest('/imroom/:apiVer/createRoom', function* (ctx) {
  18. yield F.checkParamsNull(ctx, "room_info"); // room_info参数不能为空
  19. let room_info = ctx.I.room_info;
  20. yield F.assertParamNull(room_info, "uid"); // room_info里的uid 不能为空
  21. let new_room_id = yield mgr_map.room.createRoomId(); // 生成下一个房间号
  22. room_info.roomId = new_room_id;
  23. room_info.mute = 0; //TODO 禁言功能
  24. room_info.audioChannel = yield mgr_map.redis.getRoomAudioChannel(room_info.roomId);
  25. yield mgr_map.redis.setRoomInfo(room_info.roomId, room_info);
  26. yield mgr_map.room.createRoomId();
  27. F.setResJson(ctx, 0, new_room_id);
  28. });
  29. /**
  30. * 4.5.http:修改聊天室接口(Java→IM)
  31. */
  32. http_app.regRequest('/imroom/:apiVer/updateRoomInfo', function* (ctx) {
  33. yield F.checkParamsNull(ctx, "room_info"); // room_info参数不能为空
  34. let room_info = ctx.I.room_info;
  35. yield F.assertParamNull(room_info, "uid"); // room_info里的uid 不能为空
  36. let new_room_id = 0;
  37. if (!"roomId" in room_info || F.isNull(room_info.roomId)) {
  38. new_room_id = yield mgr_map.redis.getNextReqId("room_id"); // 生成下一个房间号
  39. room_info.roomId = new_room_id;
  40. }
  41. room_info.mute = 0; //TODO 禁言功能
  42. room_info.audioChannel = yield mgr_map.redis.getRoomAudioChannel(room_info.roomId);
  43. yield mgr_map.redis.setRoomInfo(room_info.roomId, room_info);
  44. let room_socket = yield mgr_map.redis.getRoomSocketList(room_info.roomId);
  45. yield mgr_map.notice.pushChatRoomUpdatedNotice(room_socket, room_info);
  46. F.setResJson(ctx, 0, new_room_id);
  47. });
  48. /**
  49. * 4.11.http:获取聊天室基本信息(Client→Server)
  50. * room_id:房间id string
  51. * uid: 发请求的用户
  52. * ticket:发请求的用户ticket
  53. */
  54. http_app.regPost('/imroom/:apiVer/fetchRoomInfo', function* (ctx) {
  55. yield F.checkParamsNull(ctx, "room_id,uid,ticket");
  56. let room_id = ctx.I.room_id;
  57. let room_info = yield mgr_map.room.getRoomInfo(room_id);
  58. if (!F.isNull(room_info)) {
  59. room_info.onlineNum = yield mgr_map.redis.getRoomOnlineNum(room_id);
  60. }
  61. F.setResJson(ctx, 0, room_info);
  62. });
  63. /**
  64. * 4.12.http:获取聊天室成员信息(Client→Server)
  65. * room_id:房间id string
  66. * start: 整形 分页用 从哪个位置开始 0表示第一个
  67. * limit: 整数 分页用 每页个数 默认10
  68. * uid: 发请求的用户
  69. * ticket:发请求的用户ticket
  70. */
  71. http_app.regPost('/imroom/:apiVer/fetchRoomMembers', function* (ctx) {
  72. yield F.checkParamsNull(ctx, "room_id, uid, ticket, start,limit");
  73. let room_id = ctx.I.room_id;
  74. let start = parseInt(ctx.I.start);
  75. let limit = parseInt(ctx.I.limit);
  76. if (F.isNull(limit)) {
  77. limit = 10;
  78. }
  79. let uid_list = yield mgr_map.redis.getRoomUserPage(room_id, start, start + limit);
  80. let room_info = yield mgr_map.room.getRoomInfo(room_id);
  81. if (F.isNull(room_info)) {
  82. F.throwErrCode(100200);
  83. }
  84. let member_list = [];
  85. for (let i = 0; i < uid_list.length; i++) {
  86. let member = yield mgr_map.member.getJavaUserInfo(uid_list[i]);
  87. member = yield mgr_map.member.extendMemberInfo(member, room_info);
  88. member_list.push(member);
  89. }
  90. //F.addDebugLogs(["fetchRoomMembers:", member_list]);
  91. // F.addErrLogs(member_list)
  92. F.setResJson(ctx, 0, member_list);
  93. });
  94. /**
  95. * 4.14.http:根据ID获取聊天室成员信息(Client→Server)
  96. * room_id:房间id string
  97. * accounts:用户id string 示例: '123,345'
  98. * uid: 发请求的用户
  99. * ticket:发请求的用户ticket
  100. */
  101. http_app.regPost('/imroom/:apiVer/fetchRoomMembersByIds', function* (ctx) {
  102. yield F.checkParamsNull(ctx, "room_id, uid, ticket, accounts"); // ext参数不能为空
  103. let room_id = ctx.I.room_id;
  104. let accounts = ctx.I.accounts;
  105. let room_uids = yield mgr_map.redis.getRoomUserList(room_id);
  106. let room_info = yield mgr_map.room.getRoomInfo(room_id);
  107. if (F.isNull(room_info)) {
  108. F.throwErrCode(100200);
  109. }
  110. let member_list = [];
  111. if (F.isNull(room_uids)) {
  112. F.setResJson(ctx, 0, null);
  113. return;
  114. }
  115. for (let i = 0; i < room_uids.length; i++) {
  116. if ((','+accounts+',').indexOf((','+room_uids[i]+',')) == -1) {
  117. continue;
  118. }
  119. let user_info = yield mgr_map.member.getJavaUserInfo(room_uids[i]);
  120. user_info = yield mgr_map.member.extendMemberInfo(user_info, room_info);
  121. member_list.push(user_info);
  122. }
  123. F.addDebugLogs(["fetchRoomMembersByIds:", member_list]);
  124. F.setResJson(ctx, 0, member_list);
  125. });
  126. /**
  127. * 4.15.http:添加移除聊天室黑名单(Client→Server)
  128. * is_add: 整形 1:添加 0:移除
  129. * room_id:房间id string
  130. * account:要添加或移除的uid string
  131. * uid: 发请求的用户
  132. * ticket:发请求的用户ticket
  133. */
  134. http_app.regPost('/imroom/:apiVer/markChatRoomBlackList', function* (ctx) {
  135. yield F.checkParamsNull(ctx, "room_id, uid, ticket, account, is_add"); // ext参数不能为空
  136. let room_id = ctx.I.room_id;
  137. let uid = ctx.I.uid;
  138. let is_add = ctx.I.is_add;
  139. let account = ctx.I.account;
  140. let room_info = yield mgr_map.room.getRoomInfo(room_id);
  141. if (F.isNull(room_info)) {
  142. F.throwErrCode(100200);
  143. }
  144. let user_info = yield mgr_map.member.getJavaUserInfo(account);
  145. if (F.isNull(user_info)) {
  146. F.setResJson(ctx, 0);
  147. }
  148. let is_creator = yield mgr_map.validator.isRoomCreator(room_id, uid);
  149. let is_manager = yield mgr_map.validator.isRoomManager(room_id, uid);
  150. if (is_creator && is_manager) {
  151. F.throwErrCode(100405);
  152. }
  153. if (Number(is_add) == 0) {
  154. yield mgr_map.room.removeChatRoomBlackList(room_id, account);
  155. } else {
  156. yield mgr_map.room.markChatRoomBlackList(room_id, uid, account);
  157. }
  158. F.setResJson(ctx, 0);
  159. });
  160. /**
  161. * 4.18.http:设置/取消聊天室管理员(Client→Server)
  162. * is_add: 整形 1:添加 0:移除
  163. * room_id:房间id string
  164. * account:要添加或移除的uid string
  165. * uid: 发请求的用户
  166. * ticket:发请求的用户ticket
  167. */
  168. http_app.regPost('/imroom/:apiVer/markChatRoomManager', function* (ctx) {
  169. yield F.checkParamsNull(ctx, "room_id, uid, ticket, account, is_add"); // ext参数不能为空
  170. let is_add = ctx.I.is_add;
  171. let room_id = ctx.I.room_id;
  172. let account = ctx.I.account;
  173. let uid = ctx.I.uid;
  174. // 判断是否房主
  175. let is_creator = yield mgr_map.validator.isRoomCreator(room_id, uid);
  176. if (!is_creator) {
  177. F.throwErrCode(100405);
  178. }
  179. // 判断用户是否存在
  180. let user_info = yield mgr_map.member.getJavaUserInfo(account);
  181. if (F.isNull(user_info)) {
  182. F.throwErrCode(100101);
  183. }
  184. if (is_add == 1) {
  185. yield mgr_map.room.markChatRoomManager(room_id, account);
  186. } else {
  187. yield mgr_map.room.removeChatRoomManager(room_id, account);
  188. }
  189. F.setResJson(ctx, 0);
  190. });
  191. /**
  192. * 4.27.http:增加房间用户禁言接口(Client→Server)
  193. * is_mute: 是否禁言用户 1:是 0:否
  194. * room_id:房间id string
  195. * account:要添加或移除的uid string
  196. * uid: 发请求的用户
  197. * ticket:发请求的用户ticket
  198. */
  199. http_app.regPost('/imroom/:apiVer/markChatRoomMute', function* (ctx) {
  200. yield F.checkParamsNull(ctx, "room_id, uid, ticket, account, is_mute"); // ext参数不能为空
  201. let room_id = ctx.I.room_id;
  202. let uid = ctx.I.uid;
  203. let is_mute = ctx.I.is_mute;
  204. let account = ctx.I.account;
  205. let room_info = yield mgr_map.room.getRoomInfo(room_id);
  206. if (F.isNull(room_info)) {
  207. F.throwErrCode(100200);
  208. }
  209. let user_info = yield mgr_map.member.getJavaUserInfo(account);
  210. if (F.isNull(user_info)) {
  211. F.setResJson(ctx, 0);
  212. }
  213. let is_creator = yield mgr_map.validator.isRoomCreator(room_id, uid);
  214. let is_manager = yield mgr_map.validator.isRoomManager(room_id, uid);
  215. if (is_creator && is_manager) {
  216. F.throwErrCode(100405);
  217. }
  218. if (Number(is_mute) == 0) {
  219. yield mgr_map.room.removeChatRoomMute(room_id, account);
  220. } else {
  221. yield mgr_map.room.markChatRoomMute(room_id, uid, account);
  222. }
  223. F.setResJson(ctx, 0);
  224. });
  225. /**
  226. * 4.28.http:查询房间用户禁言接口
  227. * room_id:房间id string
  228. * uid: 发请求的用户
  229. * ticket:发请求的用户ticket
  230. */
  231. http_app.regPost('/imroom/:apiVer/fetchChatRoomMuteList', function* (ctx) {
  232. yield F.checkParamsNull(ctx, "room_id, uid, ticket");
  233. let uid = ctx.I.uid;
  234. let room_id = ctx.I.room_id;
  235. let room_info = yield mgr_map.room.getRoomInfo(room_id);
  236. if (F.isNull(room_info)) {
  237. F.throwErrCode(100200);
  238. }
  239. let is_creator = yield mgr_map.validator.isRoomCreator(room_id, uid);
  240. let is_manager = yield mgr_map.validator.isRoomManager(room_id, uid);
  241. if (is_creator && is_manager) {
  242. F.throwErrCode(100405);
  243. }
  244. let uid_list = yield mgr_map.redis.getRoomMute(room_id);
  245. let member_list = [];
  246. for (let i = 0; i < uid_list.length; i++) {
  247. let member = yield mgr_map.member.getJavaUserInfo(uid_list[i]);
  248. member = yield mgr_map.member.extendMemberInfo(member, room_info);
  249. member_list.push(member);
  250. }
  251. F.setResJson(ctx, 0, member_list);
  252. });
  253. /**
  254. * http:添加机器人
  255. * room_id:房间id
  256. * accounts:机器人uid string 示例: '123,345'
  257. */
  258. http_app.regPost('/imroom/:apiVer/addRobot', function* (ctx) {
  259. yield F.checkParamsNull(ctx, "room_id, accounts"); // ext参数不能为空
  260. let room_id = ctx.I.room_id;
  261. let accounts = ctx.I.accounts;
  262. let room_info = yield mgr_map.room.getRoomInfo(room_id);
  263. if (F.isNull(room_info)) {
  264. F.throwErrCode(100200);
  265. }
  266. let list = accounts.split(',');
  267. let suc = [];
  268. let err = [];
  269. for (let i = 0; i < list.length; i++) {
  270. let member = yield mgr_map.member.getJavaUserInfo(list[i]);
  271. if (F.isNull(member)) {
  272. err.push(list[i]);
  273. continue;
  274. } else {
  275. suc.push(list[i]);
  276. }
  277. // 把该用户的旧socket踢出,目前业务逻辑是 一个用户同一时刻只有一个socket
  278. let old_socket_list = yield mgr_map.redis.getUserSocketList(list[i]);
  279. for (let i = 0; i < old_socket_list.length; i++) {
  280. yield mgr_map.im.delSvrMap(old_socket_list[i]); // 服务器主动断开socket
  281. yield mgr_map.redis.delUserSocketList(list[i], old_socket_list[i]); // 删除用户socket记录,其实socket断开处理abnormalClose函数也会删除
  282. }
  283. let connect_time = new Date().getTime();
  284. let cur_time_num = yield mgr_map.redis.getNextExpireId(connect_time);
  285. let uniid = _.str.vsprintf("%s_%s_%s_%s_%s", ['robot', cur_time_num, connect_time, list[i]]); // 就是socketid保证跨服务器唯一
  286. yield mgr_map.redis.addSocketToUser(list[i], uniid); // 记录该用户有那些socket
  287. // 在这里把离开用户之前进的房间
  288. yield mgr_map.room.leavePreRoom(list[i]);
  289. yield mgr_map.member.extendMemberInfo(member, room_info);
  290. yield mgr_map.room.enterRoom(list[i], uniid, room_id); // 执行进入房间函数
  291. }
  292. let result = {
  293. suc: suc,
  294. err: err
  295. };
  296. F.setResJson(ctx, 0, result);
  297. });
  298. /**
  299. * http:删除机器人
  300. * room_id:房间id
  301. * accounts:机器人uid string 示例: '123,345'
  302. */
  303. http_app.regPost('/imroom/:apiVer/delRobot', function* (ctx) {
  304. yield F.checkParamsNull(ctx, "room_id, accounts"); // ext参数不能为空
  305. let room_id = ctx.I.room_id;
  306. let accounts = ctx.I.accounts;
  307. let list = accounts.split(',');
  308. let suc = [];
  309. let err = [];
  310. for (let i = 0; i < list.length; i++) {
  311. let uniid = yield mgr_map.redis.getUserSocketList(list[i]); // 获取该用户有那些socket
  312. if (F.isNull(uniid)) {
  313. err.push(list[i]);
  314. continue;
  315. } else {
  316. suc.push(list[i]);
  317. }
  318. yield mgr_map.room.leaveRoom(list[i], uniid, room_id);
  319. }
  320. let result = {
  321. suc: suc,
  322. err: err
  323. };
  324. F.setResJson(ctx, 0, result);
  325. });
  326. /**
  327. * 切换声网即构
  328. */
  329. http_app.regGet('/imroom/:apiVer/changeAudioChannel', function* (ctx) {
  330. yield F.checkParamsNull(ctx, "audio_channel"); // audio_channel参数不能为空
  331. let audio_channel = ctx.I.audio_channel;
  332. if (audio_channel != 1 && audio_channel != 2 && audio_channel != 3) {
  333. F.throwErrCode(100204);
  334. }
  335. let room_id = ctx.I.room_id;
  336. yield mgr_map.room.changeAudioChannel(audio_channel, room_id);
  337. F.setResJson(ctx, 0);
  338. });
  339. /**
  340. * 获取用户房间内角色
  341. */
  342. http_app.regGet('/imroom/:apiVer/getRoomMemberRole', function* (ctx) {
  343. yield F.checkParamsNull(ctx, "room_id,uid"); // audio_channel参数不能为空
  344. let room_id = ctx.I.room_id;
  345. let uid = ctx.I.uid;
  346. let res = yield mgr_map.room.getRoomMemberRole(room_id, uid);
  347. F.setResJson(ctx, 0, res);
  348. });
  349. /**
  350. * 检查是否可以推流接口
  351. */
  352. http_app.regRequest('/imroom/:apiVer/checkPushAuth',function* (ctx) {
  353. yield F.checkParamsNull(ctx, "room_id,uid,ticket"); // audio_channel参数不能为空
  354. let room_id = ctx.I.room_id;
  355. let uid = ctx.I.uid;
  356. let ticket = ctx.I.ticket;
  357. let cache_ticket = yield mgr_map.javaRedis.getTicketByUid(uid);
  358. if (ticket != cache_ticket) F.throwErrCode(100100);
  359. let in_que = yield mgr_map.redis.checkInQueue(room_id,uid);
  360. if (!in_que) {
  361. //yield mgr_map.roomQueue.delFromRoomQueueByUid(uid,room_id,uid);
  362. F.throwErrCode(100302);
  363. }
  364. F.setResJson(ctx, 0);
  365. });
  366. http_app.regRequest('/imroom/:apiVer/createStream',function* (ctx) {
  367. yield F.checkParamsNull(ctx, "channel_id,publish_id,stream_alias,stream_sid"); // audio_channel参数不能为空
  368. let room_id = ctx.I.channel_id;
  369. let uid = ctx.I.publish_id;
  370. let streamid = ctx.I.stream_alias;
  371. let streamsvrid = ctx.I.stream_sid;
  372. yield mgr_map.redis.setStreamId(uid,streamid);
  373. yield mgr_map.redis.setStreamSvrId(uid,streamsvrid);
  374. let in_que = yield mgr_map.redis.checkInQueue(room_id,uid);
  375. F.addDebugLogs(["##########inque",in_que, uid]);
  376. //if (!in_que && "10045146" != room_id) {
  377. if (!in_que) {
  378. yield mgr_map.roomQueue.delFromRoomQueueByUid(uid,room_id,uid);
  379. co(mgr_map.extrn.delZegoStream(room_id,uid));
  380. // F.throwErrCode(100302);
  381. }
  382. ctx.body = 1;
  383. });
  384. http_app.regRequest('/imroom/:apiVer/closeStream',function* (ctx) {
  385. ctx.body = 1;
  386. });
  387. };