You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

248 lines
5.7 KiB

  1. var app = require('express')();
  2. var http = require('http').Server(app);
  3. var io = require('socket.io')(http);
  4. var cookie = require('cookie')
  5. var fs = require('fs');
  6. var redis = require("redis")
  7. var subscriber = redis.createClient(12311);
  8. var request = require('superagent')
  9. var default_site;
  10. if(fs.existsSync('sites/currentsite.txt')) {
  11. default_site = fs.readFileSync('sites/currentsite.txt').toString().trim();
  12. }
  13. app.get('/', function(req, res){
  14. res.sendfile('index.html');
  15. });
  16. io.on('connection', function(socket){
  17. if (get_hostname(socket.request.headers.host) != get_hostname(socket.request.headers.origin)) {
  18. return;
  19. }
  20. // console.log("connection!");
  21. var sid = cookie.parse(socket.request.headers.cookie).sid
  22. if(!sid) {
  23. return;
  24. }
  25. socket.user = cookie.parse(socket.request.headers.cookie).user_id;
  26. // console.log("firing get_user_info");
  27. request.get(get_url(socket, '/api/method/frappe.async.get_user_info'))
  28. .type('form')
  29. .send({
  30. sid: sid
  31. })
  32. .end(function(err, res) {
  33. if(err) {
  34. console.log(err);
  35. return;
  36. }
  37. if(res.status == 200) {
  38. var room = get_user_room(socket, res.body.message.user);
  39. // console.log('joining', room);
  40. socket.join(room);
  41. socket.join(get_site_room(socket));
  42. }
  43. });
  44. socket.on('task_subscribe', function(task_id) {
  45. var room = 'task:' + task_id;
  46. socket.join(room);
  47. });
  48. socket.on('progress_subscribe', function(task_id) {
  49. var room = 'task_progress:' + task_id;
  50. socket.join(room);
  51. send_existing_lines(task_id, socket);
  52. });
  53. socket.on('doc_subscribe', function(doctype, docname) {
  54. // console.log('trying to subscribe', doctype, docname)
  55. can_subscribe_doc({
  56. socket: socket,
  57. sid: sid,
  58. doctype: doctype,
  59. docname: docname,
  60. callback: function(err, res) {
  61. var room = get_doc_room(socket, doctype, docname);
  62. // console.log('joining', room)
  63. socket.join(room);
  64. }
  65. });
  66. });
  67. socket.on('doc_unsubscribe', function(doctype, docname) {
  68. var room = get_doc_room(socket, doctype, docname);
  69. socket.leave(room);
  70. });
  71. socket.on('doc_open', function(doctype, docname) {
  72. // show who is currently viewing the form
  73. can_subscribe_doc({
  74. socket: socket,
  75. sid: sid,
  76. doctype: doctype,
  77. docname: docname,
  78. callback: function(err, res) {
  79. var room = get_open_doc_room(socket, doctype, docname);
  80. // console.log('joining', room)
  81. socket.join(room);
  82. send_viewers({
  83. socket: socket,
  84. doctype: doctype,
  85. docname: docname,
  86. });
  87. }
  88. });
  89. });
  90. socket.on('doc_close', function(doctype, docname) {
  91. // remove this user from the list of 'who is currently viewing the form'
  92. var room = get_open_doc_room(socket, doctype, docname);
  93. socket.leave(room);
  94. send_viewers({
  95. socket: socket,
  96. doctype: doctype,
  97. docname: docname,
  98. });
  99. });
  100. // socket.on('disconnect', function (arguments) {
  101. // console.log("user disconnected", arguments);
  102. // });
  103. });
  104. function send_existing_lines(task_id, socket) {
  105. subscriber.hgetall('task_log:' + task_id, function(err, lines) {
  106. socket.emit('task_progress', {
  107. "task_id": task_id,
  108. "message": {
  109. "lines": lines
  110. }
  111. })
  112. })
  113. }
  114. subscriber.on("message", function(channel, message) {
  115. message = JSON.parse(message);
  116. io.to(message.room).emit(message.event, message.message);
  117. // console.log(message.room, message.event, message.message)
  118. });
  119. subscriber.subscribe("events");
  120. http.listen(3000, function(){
  121. console.log('listening on *:3000');
  122. });
  123. function get_doc_room(socket, doctype, docname) {
  124. return get_site_name(socket) + ':doc:'+ doctype + '/' + docname;
  125. }
  126. function get_open_doc_room(socket, doctype, docname) {
  127. return get_site_name(socket) + ':open_doc:'+ doctype + '/' + docname;
  128. }
  129. function get_user_room(socket, user) {
  130. return get_site_name(socket) + ':user:' + user;
  131. }
  132. function get_site_room(socket) {
  133. return get_site_name(socket) + ':all';
  134. }
  135. function get_site_name(socket) {
  136. if (default_site) {
  137. return default_site;
  138. }
  139. else if (socket.request.headers['x-frappe-site-name']) {
  140. return get_hostname(socket.request.headers['x-frappe-site-name']);
  141. }
  142. else if (socket.request.headers.origin) {
  143. return get_hostname(socket.request.headers.origin);
  144. }
  145. else {
  146. return get_hostname(socket.request.headers.host);
  147. }
  148. }
  149. function get_hostname(url) {
  150. if (!url) return undefined;
  151. if (url.indexOf("://") > -1) {
  152. url = url.split('/')[2];
  153. }
  154. return ( url.match(/:/g) ) ? url.slice( 0, url.indexOf(":") ) : url
  155. }
  156. function get_url(socket, path) {
  157. if (!path) {
  158. path = '';
  159. }
  160. return socket.request.headers.origin + path;
  161. }
  162. function can_subscribe_doc(args) {
  163. request.get(get_url(args.socket, '/api/method/frappe.async.can_subscribe_doc'))
  164. .type('form')
  165. .send({
  166. sid: args.sid,
  167. doctype: args.doctype,
  168. docname: args.docname
  169. })
  170. .end(function(err, res) {
  171. if (!res) {
  172. console.log("No response for doc_subscribe");
  173. } else if (res.status == 403) {
  174. return;
  175. } else if (err) {
  176. console.log(err);
  177. } else if (res.status == 200) {
  178. args.callback(err, res);
  179. } else {
  180. console.log("Something went wrong", err, res);
  181. }
  182. });
  183. }
  184. function send_viewers(args) {
  185. // send to doc room, 'users currently viewing this document'
  186. if (!(args && args.doctype && args.docname)) {
  187. return;
  188. }
  189. // open doc room
  190. var room = get_open_doc_room(args.socket, args.doctype, args.docname);
  191. // socket ids connected to this room
  192. var clients = Object.keys(io.sockets.adapter.rooms[room] || {});
  193. var viewers = [];
  194. for (var i in io.sockets.sockets) {
  195. var s = io.sockets.sockets[i];
  196. if (clients.indexOf(s.id)!==-1) {
  197. // this socket is connected to the room
  198. viewers.push(s.user);
  199. }
  200. }
  201. // notify
  202. io.to(room).emit("doc_viewers", {
  203. doctype: args.doctype,
  204. docname: args.docname,
  205. viewers: viewers
  206. });
  207. }