25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

194 lines
4.6 KiB

  1. const { xhiveframework_request } = require("../utils");
  2. const log = console.log;
  3. const WEBSITE_ROOM = "website";
  4. const SITE_ROOM = "all";
  5. function xhiveframework_handlers(realtime, socket) {
  6. socket.join(user_room(socket.user));
  7. socket.join(WEBSITE_ROOM);
  8. if (socket.user_type == "System User") {
  9. socket.join(SITE_ROOM);
  10. }
  11. socket.on("doctype_subscribe", function (doctype) {
  12. can_subscribe_doctype({
  13. socket,
  14. doctype,
  15. callback: () => {
  16. socket.join(doctype_room(doctype));
  17. },
  18. });
  19. });
  20. socket.on("doctype_unsubscribe", function (doctype) {
  21. socket.leave(doctype_room(doctype));
  22. });
  23. socket.on("task_subscribe", function (task_id) {
  24. const room = task_room(task_id);
  25. socket.join(room);
  26. });
  27. socket.on("task_unsubscribe", function (task_id) {
  28. const room = task_room(task_id);
  29. socket.leave(room);
  30. });
  31. socket.on("progress_subscribe", function (task_id) {
  32. const room = task_room(task_id);
  33. socket.join(room);
  34. });
  35. socket.on("doc_subscribe", function (doctype, docname) {
  36. can_subscribe_doc({
  37. socket,
  38. doctype,
  39. docname,
  40. callback: () => {
  41. let room = doc_room(doctype, docname);
  42. socket.join(room);
  43. },
  44. });
  45. });
  46. socket.on("doc_unsubscribe", function (doctype, docname) {
  47. let room = doc_room(doctype, docname);
  48. socket.leave(room);
  49. });
  50. socket.on("doc_open", function (doctype, docname) {
  51. can_subscribe_doc({
  52. socket,
  53. doctype,
  54. docname,
  55. callback: () => {
  56. let room = open_doc_room(doctype, docname);
  57. socket.join(room);
  58. if (!socket.subscribed_documents) socket.subscribed_documents = [];
  59. socket.subscribed_documents.push([doctype, docname]);
  60. // show who is currently viewing the form
  61. notify_subscribed_doc_users({
  62. socket: socket,
  63. doctype: doctype,
  64. docname: docname,
  65. });
  66. },
  67. });
  68. });
  69. socket.on("doc_close", function (doctype, docname) {
  70. // remove this user from the list of 'who is currently viewing the form'
  71. let room = open_doc_room(doctype, docname);
  72. socket.leave(room);
  73. if (socket.subscribed_documents) {
  74. socket.subscribed_documents = socket.subscribed_documents.filter(([dt, dn]) => {
  75. !(dt == doctype && dn == docname);
  76. });
  77. }
  78. notify_subscribed_doc_users({
  79. socket: socket,
  80. doctype: doctype,
  81. docname: docname,
  82. });
  83. });
  84. socket.on("disconnect", () => {
  85. notify_disconnected_documents(socket);
  86. });
  87. }
  88. function notify_disconnected_documents(socket) {
  89. if (socket.subscribed_documents) {
  90. socket.subscribed_documents.forEach(([doctype, docname]) => {
  91. notify_subscribed_doc_users({ socket, doctype, docname });
  92. });
  93. }
  94. }
  95. function can_subscribe_doctype(args) {
  96. if (!args) return;
  97. if (!args.doctype) return;
  98. xhiveframework_request("/api/method/xhiveframework.realtime.can_subscribe_doctype", args.socket)
  99. .type("form")
  100. .query({
  101. doctype: args.doctype,
  102. })
  103. .end(function (err, res) {
  104. if (!res || res.status == 403 || err) {
  105. if (err) {
  106. log(err);
  107. }
  108. return false;
  109. } else if (res.status == 200) {
  110. args.callback && args.callback(err, res);
  111. return true;
  112. }
  113. log("ERROR (can_subscribe_doctype): ", err, res);
  114. });
  115. }
  116. function notify_subscribed_doc_users(args) {
  117. if (!(args && args.doctype && args.docname)) {
  118. return;
  119. }
  120. const socket = args.socket;
  121. const room = open_doc_room(args.doctype, args.docname);
  122. const clients = Array.from(socket.nsp.adapter.rooms.get(room) || []);
  123. let users = [];
  124. socket.nsp.sockets.forEach((sock) => {
  125. if (clients.includes(sock.id)) {
  126. users.push(sock.user);
  127. }
  128. });
  129. // dont send update to self. meaningless.
  130. if (users.length == 1 && users[0] == args.socket.user) return;
  131. // notify
  132. socket.nsp.to(room).emit("doc_viewers", {
  133. doctype: args.doctype,
  134. docname: args.docname,
  135. users: Array.from(new Set(users)),
  136. });
  137. }
  138. function can_subscribe_doc(args) {
  139. if (!args) return;
  140. if (!args.doctype || !args.docname) return;
  141. xhiveframework_request("/api/method/xhiveframework.realtime.can_subscribe_doc", args.socket)
  142. .type("form")
  143. .query({
  144. doctype: args.doctype,
  145. docname: args.docname,
  146. })
  147. .end(function (err, res) {
  148. if (!res) {
  149. log("No response for doc_subscribe");
  150. } else if (res.status == 403) {
  151. return;
  152. } else if (err) {
  153. log(err);
  154. } else if (res.status == 200) {
  155. args.callback(err, res);
  156. } else {
  157. log("Something went wrong", err, res);
  158. }
  159. });
  160. }
  161. const doc_room = (doctype, docname) => "doc:" + doctype + "/" + docname;
  162. const open_doc_room = (doctype, docname) => "open_doc:" + doctype + "/" + docname;
  163. const user_room = (user) => "user:" + user;
  164. const doctype_room = (doctype) => "doctype:" + doctype;
  165. const task_room = (task_id) => "task_progress:" + task_id;
  166. module.exports = xhiveframework_handlers;