udpconnector.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. var net = require('net');
  2. var util = require('util');
  3. var dgram = require("dgram");
  4. var utils = require('../util/utils');
  5. var Constants = require('../util/constants');
  6. var UdpSocket = require('./udpsocket');
  7. var Kick = require('./commands/kick');
  8. var Handshake = require('./commands/handshake');
  9. var Heartbeat = require('./commands/heartbeat');
  10. var protocol = require('pomelo-protocol');
  11. var Package = protocol.Package;
  12. var Message = protocol.Message;
  13. var coder = require('./common/coder');
  14. var EventEmitter = require('events').EventEmitter;
  15. var curId = 1;
  16. var Connector = function(port, host, opts) {
  17. if (!(this instanceof Connector)) {
  18. return new Connector(port, host, opts);
  19. }
  20. EventEmitter.call(this);
  21. this.opts = opts || {};
  22. this.type = opts.udpType || 'udp4';
  23. this.handshake = new Handshake(opts);
  24. if(!opts.heartbeat) {
  25. opts.heartbeat = Constants.TIME.DEFAULT_UDP_HEARTBEAT_TIME;
  26. opts.timeout = Constants.TIME.DEFAULT_UDP_HEARTBEAT_TIMEOUT;
  27. }
  28. this.heartbeat = new Heartbeat(utils.extends(opts, {disconnectOnTimeout: true}));
  29. this.clients = {};
  30. this.host = host;
  31. this.port = port;
  32. };
  33. util.inherits(Connector, EventEmitter);
  34. module.exports = Connector;
  35. Connector.prototype.start = function(cb) {
  36. var self = this;
  37. this.tcpServer = net.createServer();
  38. this.socket = dgram.createSocket(this.type, function(msg, peer) {
  39. var key = genKey(peer);
  40. if(!self.clients[key]) {
  41. var udpsocket = new UdpSocket(curId++, self.socket, peer);
  42. self.clients[key] = udpsocket;
  43. udpsocket.on('handshake',
  44. self.handshake.handle.bind(self.handshake, udpsocket));
  45. udpsocket.on('heartbeat',
  46. self.heartbeat.handle.bind(self.heartbeat, udpsocket));
  47. udpsocket.on('disconnect',
  48. self.heartbeat.clear.bind(self.heartbeat, udpsocket.id));
  49. udpsocket.on('disconnect', function() {
  50. delete self.clients[genKey(udpsocket.peer)];
  51. });
  52. udpsocket.on('closing', Kick.handle.bind(null, udpsocket));
  53. self.emit('connection', udpsocket);
  54. }
  55. });
  56. this.socket.on('message', function(data, peer) {
  57. var socket = self.clients[genKey(peer)];
  58. if(!!socket) {
  59. socket.emit('package', data);
  60. }
  61. });
  62. this.socket.on('error', function(err) {
  63. logger.error('udp socket encounters with error: %j', err.stack);
  64. return;
  65. });
  66. this.socket.bind(this.port, this.host);
  67. this.tcpServer.listen(this.port);
  68. process.nextTick(cb);
  69. };
  70. Connector.decode = Connector.prototype.decode = coder.decode;
  71. Connector.encode = Connector.prototype.encode = coder.encode;
  72. Connector.prototype.stop = function(force, cb) {
  73. this.socket.close();
  74. process.nextTick(cb);
  75. };
  76. var genKey = function(peer) {
  77. return peer.address + ":" + peer.port;
  78. };