UNPKG

eazy-pomelo

Version:
124 lines (99 loc) 4.01 kB
const net = require('net'); const util = require('util'); const dgram = require('dgram'); const EventEmitter = require('events').EventEmitter; const utils = require('../util/utils'); const KCPSocket = require('./kcpsocket'); const Kick = require('./commands/kick'); const Handshake = require('./commands/handshake'); const Heartbeat = require('./commands/heartbeat'); const coder = require('./common/coder'); const DEFAULT_SOCKET_TIMEOUT = 90; //second var curId = 1; var Connector = function(port, host, opts) { if (!(this instanceof Connector)) { return new Connector(port, host, opts); } EventEmitter.call(this); this.opts = opts || {}; this.host = host; this.port = port; this.useDict = opts.useDict; this.useProtobuf = opts.useProtobuf; this.clients = {}; this.handshake = null; this.heartbeat = null; } util.inherits(Connector, EventEmitter); module.exports = Connector; Connector.prototype.start = function(cb) { let self = this; let app = require('../pomelo').app; this.connector = app.components.__connector__.connector; this.dictionary = app.components.__dictionary__; this.protobuf = app.components.__protobuf__; this.decodeIO_protobuf = app.components.__decodeIO__protobuf__; //this.server = net.createServer(); this.socket = dgram.createSocket(this.opts.udpType || 'udp4'); this.socket.on('message', function(msg, peer){ //console.log(peer); self.bindSocket(self.socket, peer.address, peer.port, msg); }); this.socket.on('error', function(error) { return; }); this.socket.bind(this.port); //this.server.listen(this.port); process.nextTick(cb); } Connector.prototype.bindSocket = function(socket, address, port, msg) { let self = this; let key = genKey(address, port); let kcpsocket = self.clients[key]; let opts = self.opts; if (!kcpsocket) { self.clients[key] = new KCPSocket(curId++, socket, address, port, opts); kcpsocket = self.clients[key]; self.handshake = self.handshake || new Handshake(opts); if (!self.heartbeat) { if(!opts.heartbeat) { opts.heartbeat = Math.max(1, opts.interval / 1000); opts.timeout = opts.heartbeat * 2; } if ((opts.heartbeat * 1000) < opts.interval) { console.warn('heartbeat interval must longer than kcp interval'); opts.heartbeat = opts.interval; } if ((opts.timeout * 1000) < 2 * opts.interval) { console.warn('timeout must longer than kcp interval * 2'); opts.timeout = opts.heartbeat * 2; } self.heartbeat = new Heartbeat(utils.extends(opts, {disconnectOnTimeout: true})); } kcpsocket.on('handshake', self.handshake.handle.bind(self.handshake, kcpsocket)); kcpsocket.on('heartbeat', self.heartbeat.handle.bind(self.heartbeat, kcpsocket)); //kcpsocket.on('disconnect', self.heartbeat.clear.bind(self.heartbeat, kcpsocket.id)); kcpsocket.on('disconnect', function(){ self.heartbeat.clear(kcpsocket.id); Kick.handle(kcpsocket, 'disconnet'); process.nextTick(function() { kcpsocket.removeAllListeners(); delete self.clients[key]; }); }); //kcpsocket.on('closing', Kick.handle.bind(null, kcpsocket)); self.emit('connection', kcpsocket); } if (!!msg) { kcpsocket.emit('input', msg); } } Connector.prototype.stop = function(force, cb) { this.socket.close(); process.nextTick(cb); }; Connector.decode = Connector.prototype.decode = coder.decode; Connector.encode = Connector.prototype.encode = coder.encode; var genKey = function(address, port) { return address + ':' + port; }