pinusmod-kcp2
Version:
kcp 的 connector,基于 kcpjs
121 lines (120 loc) • 3.92 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.KcpSocket = void 0;
/**
* Copyright 2016 leenjewel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const path = require("path");
const pinusmod_logger_1 = require("pinusmod-logger");
let logger = (0, pinusmod_logger_1.getLogger)('pinus', path.basename(__filename));
const events_1 = require("events");
const pinuscoder = require("./pinuscoder");
const protocol = require("pinusmod-protocol");
const Package = protocol.Package;
const const_1 = require("../const/const");
class KcpSocket extends events_1.EventEmitter {
constructor(id, sess, opts) {
super();
this.id = id;
this.sess = sess;
this.host = sess.host;
this.port = sess.port;
this.remoteAddress = {
ip: this.host,
port: this.port
};
this.opts = opts;
const conv = opts.conv || 123;
this.headerSize = 0;
if (!!opts) {
this.heartbeatOnData = !!opts.heartbeatOnData;
const nodelay = opts.nodelay || 0;
const interval = opts.interval || 100;
const resend = opts.resend || 0;
const nc = opts.nc || 0;
this.sess.setNoDelay(nodelay, interval, resend, nc);
const sndwnd = opts.sndwnd || 32;
const rcvwnd = opts.rcvwnd || sndwnd;
this.sess.setWindowSize(sndwnd, rcvwnd);
const mtu = opts.mtu || 1400;
this.sess.setMtu(mtu);
}
const thiz = this;
this.sess.on('recv', (buff) => {
pinuscoder.handlePackage(thiz, buff);
});
this.state = const_1.NetState.INITED;
// 超时还未握手就绪,就删除此 socket
this._initTimer = setTimeout(() => {
if (this.state !== const_1.NetState.WORKING) {
this.disconnect();
}
this._initTimer = null;
}, 5000);
}
send(msg) {
if (this.state != const_1.NetState.WORKING) {
return;
}
if (typeof msg === 'string') {
msg = Buffer.from(msg);
}
else if (!(msg instanceof Buffer)) {
msg = Buffer.from(JSON.stringify(msg));
}
this.sendRaw(Package.encode(Package.TYPE_DATA, msg));
}
sendRaw(msg) {
if (!this.sess) {
return;
}
this.sess.write(msg);
}
sendForce(msg) {
if (this.state == const_1.NetState.CLOSED) {
return;
}
this.sendRaw(msg);
}
sendBatch(msgs) {
if (this.state != const_1.NetState.WORKING) {
return;
}
const rs = [];
for (let i = 0; i < msgs.length; i++) {
rs.push(Package.encode(Package.TYPE_DATA, msgs[i]));
}
this.sess.writeBuffers(rs);
}
handshakeResponse(resp) {
if (this.state !== const_1.NetState.INITED) {
return;
}
this.sendRaw(resp);
this.state = const_1.NetState.WAIT_ACK;
}
disconnect() {
if (this.state == const_1.NetState.CLOSED) {
return;
}
this.state = const_1.NetState.CLOSED;
this.emit('disconnect', 'kcp connection disconnected');
if (this.sess) {
this.sess.close();
this.sess = null;
}
}
}
exports.KcpSocket = KcpSocket;