server.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. var WebSocketServer = require('ws').Server
  2. var http = require('http')
  3. var websocket = require('websocket-stream')
  4. var through = require('through2');
  5. var debug = require('debug')('server');
  6. var url = module.exports.url = 'ws://localhost:' + module.exports.port
  7. var bpipes = {};
  8. var browsers = {};
  9. var server;
  10. module.exports.start = function(opts, cb) {
  11. if (typeof opts == 'function') {
  12. cb = opts;
  13. opts = {};
  14. }
  15. opts = opts || {};
  16. var port = opts.port || 8001;
  17. var wssOpts = {};
  18. if (typeof opts.server === "undefined") {
  19. server = http.createServer();
  20. wssOpts.server = server;
  21. } else {
  22. server = opts.server
  23. wssOpts.server = server;
  24. }
  25. var wss = new WebSocketServer(wssOpts)
  26. wss.on('connection', function(ws) {
  27. var stream = websocket(ws);
  28. stream.pipe(through(function(chunk, enc, cb) {
  29. debug('getting data from stream', chunk.toString())
  30. var data = JSON.parse(chunk.toString());
  31. // determine if websocket connection is from browser or from command line
  32. if (data.source === "browser") {
  33. // new browser connecting for the first time
  34. if (typeof data.id !== "undefined") {
  35. debug('new browser being added', data.id)
  36. browsers[data.id] = {
  37. stream: stream,
  38. url: data.url
  39. };
  40. // check to see if any streams are waiting for potential events
  41. for (var bpipe in bpipes) {
  42. // re-run all listening pipes on new browser
  43. var send = {
  44. "selector": bpipes[bpipe].selector,
  45. "event": bpipes[bpipe].event,
  46. "source": "bpipe",
  47. "url": data.url
  48. };
  49. var found = false;
  50. if (bpipe === data.url) {
  51. found = true;
  52. debug('trying to send out', bpipe, send)
  53. stream.write(JSON.stringify(send));
  54. }
  55. }
  56. if(!found) {
  57. debug('trying to send out', 'default', send)
  58. if (typeof bpipes['default'] !== "undefined" && bpipes['default'].stream !== "undefined") {
  59. try {
  60. // TODO: there should be an event that is emitted when stream.write is no longer open
  61. bpipes['default'].stream.write(JSON.stringify(send));
  62. } catch(err) {
  63. // browser stream is no longer there, delete it so we don't attempt to write again
  64. delete bpipes['default'];
  65. }
  66. }
  67. }
  68. }
  69. // then pipe the information back to bpipe connection looking for el
  70. var found = false;
  71. if (typeof bpipes[data.url] !== 'undefined' && typeof bpipes[data.url][data.selector] !== "undefined") {
  72. found = true;
  73. bpipes[data.url][data.selector].stream.write(chunk.toString())
  74. }
  75. if (!found) {
  76. debug('trying to send out', 'default', send)
  77. if (typeof bpipes['default'] !== "undefined" && bpipes['default'][data.selector] !== "undefined" && bpipes['default'][data.selector].stream !== "undefined") {
  78. bpipes['default'][data.selector].stream.write(chunk.toString());
  79. }
  80. }
  81. } else {
  82. if (typeof bpipes[data.url] === 'undefined') {
  83. bpipes[data.url] = {};
  84. }
  85. // then data is coming from bpipe, send it to the browser
  86. bpipes[data.url][data.selector] = {
  87. stream: stream,
  88. selector: data.selector,
  89. event: data.event,
  90. url: data.url
  91. };
  92. for (var browser in browsers) {
  93. if(browsers[browser].url === data.url || data.url === "default") {
  94. try {
  95. // TODO: there should be an event that is emitted when stream.write is no longer open
  96. browsers[browser].stream.write(chunk.toString())
  97. debug('writing to ' + data.url)
  98. } catch(err) {
  99. // browser stream is no longer there, delete it so we don't attempt to write again
  100. delete browsers[browser];
  101. }
  102. }
  103. }
  104. }
  105. cb();
  106. }))
  107. });
  108. server.listen(port, function(err){
  109. cb(null, server);
  110. })
  111. }
  112. module.exports.stop = function(cb) {
  113. if (!server) {
  114. cb(new Error('not started'))
  115. return
  116. }
  117. server.close(cb)
  118. server = null
  119. }