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.

socketio.js 5.7 KiB

10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
10 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. }