switcher.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. var EventEmitter = require('events').EventEmitter;
  2. var util = require('util');
  3. var WSProcessor = require('./wsprocessor');
  4. var TCPProcessor = require('./tcpprocessor');
  5. var logger = require('pomelo-logger').getLogger('pomelo', __filename);
  6. var HTTP_METHODS = [
  7. 'GET', 'POST', 'DELETE', 'PUT', 'HEAD'
  8. ];
  9. var ST_STARTED = 1;
  10. var ST_CLOSED = 2;
  11. var DEFAULT_TIMEOUT = 90;
  12. /**
  13. * Switcher for tcp and websocket protocol
  14. *
  15. * @param {Object} server tcp server instance from node.js net module
  16. */
  17. var Switcher = function(server, opts) {
  18. EventEmitter.call(this);
  19. this.server = server;
  20. this.wsprocessor = new WSProcessor();
  21. this.tcpprocessor = new TCPProcessor(opts.closeMethod);
  22. this.id = 1;
  23. this.timers = {};
  24. this.timeout = opts.timeout || DEFAULT_TIMEOUT;
  25. this.setNoDelay = opts.setNoDelay;
  26. this.server.on('connection', this.newSocket.bind(this));
  27. this.wsprocessor.on('connection', this.emit.bind(this, 'connection'));
  28. this.tcpprocessor.on('connection', this.emit.bind(this, 'connection'));
  29. this.state = ST_STARTED;
  30. };
  31. util.inherits(Switcher, EventEmitter);
  32. module.exports = Switcher;
  33. Switcher.prototype.newSocket = function(socket) {
  34. if(this.state !== ST_STARTED) {
  35. return;
  36. }
  37. // if set connection timeout
  38. if(!!this.timeout) {
  39. var timer = setTimeout(function() {
  40. logger.warn('connection is timeout without communication, the remote ip is %s && port is %s', socket.remoteAddress, socket.remotePort);
  41. socket.destroy();
  42. }, this.timeout * 1000);
  43. this.timers[this.id] = timer;
  44. socket.id = this.id++;
  45. }
  46. var self = this;
  47. socket.once('close', function() {
  48. if (!!socket.id) {
  49. clearTimeout(self.timers[socket.id]);
  50. delete self.timers[socket.id];
  51. }
  52. });
  53. socket.once('data', function(data) {
  54. if(!!socket.id) {
  55. clearTimeout(self.timers[socket.id]);
  56. delete self.timers[socket.id];
  57. }
  58. if(isHttp(data)) {
  59. processHttp(self, self.wsprocessor, socket, data);
  60. } else {
  61. if(!!self.setNoDelay) {
  62. socket.setNoDelay(true);
  63. }
  64. processTcp(self, self.tcpprocessor, socket, data);
  65. }
  66. });
  67. };
  68. Switcher.prototype.close = function() {
  69. if(this.state !== ST_STARTED) {
  70. return;
  71. }
  72. this.state = ST_CLOSED;
  73. this.wsprocessor.close();
  74. this.tcpprocessor.close();
  75. };
  76. var isHttp = function(data) {
  77. var head = data.toString('utf8', 0, 4);
  78. for(var i=0, l=HTTP_METHODS.length; i<l; i++) {
  79. if(head.indexOf(HTTP_METHODS[i]) === 0) {
  80. return true;
  81. }
  82. }
  83. return false;
  84. };
  85. var processHttp = function(switcher, processor, socket, data) {
  86. processor.add(socket, data);
  87. };
  88. var processTcp = function(switcher, processor, socket, data) {
  89. processor.add(socket, data);
  90. };