@runejs/common
Version:
Common logging, networking, compression, and other miscellaneous functionality for RuneJS.
102 lines • 3.92 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SocketServer = exports.SocketServerOptions = void 0;
const net_1 = require("net");
const buffer_1 = require("../buffer");
const logger_1 = require("../logger");
const connection_status_1 = require("./connection-status");
const util_1 = require("../util");
class SocketServerOptions {
constructor(props) {
this.handshakeRequired = true;
this.noDelay = true;
this.keepAlive = true;
this.timeout = 30000;
(0, util_1.setObjectProps)(this, props);
}
}
exports.SocketServerOptions = SocketServerOptions;
class SocketServer {
constructor(socket, options) {
this._connectionStatus = connection_status_1.ConnectionStatus.HANDSHAKE;
this.socket = socket;
this.options = new SocketServerOptions(options);
socket.setNoDelay(this.options.noDelay);
socket.setKeepAlive(this.options.keepAlive);
socket.setTimeout(this.options.timeout);
if (!this.options.handshakeRequired) {
this._connectionStatus = connection_status_1.ConnectionStatus.ACTIVE;
}
socket.on('data', data => {
try {
this.dataReceived(data);
}
catch (e) {
this.error(e);
}
});
socket.on('close', hadError => {
if (hadError) {
this.error(new Error('Socket closed unexpectedly!'));
}
else {
this.closeConnection();
}
});
socket.on('error', error => this.error(error));
}
static launch(serverName, hostName, port, socketServerFactory) {
const server = (0, net_1.createServer)(socket => {
socketServerFactory(socket);
}).listen(port, hostName);
logger_1.logger.info(`${serverName} listening @ ${hostName}:${port}.`);
return server;
}
dataReceived(data) {
if (!data) {
return;
}
const byteBuffer = buffer_1.ByteBuffer.fromNodeBuffer(data);
if (this.options.handshakeRequired && this.connectionStatus === connection_status_1.ConnectionStatus.HANDSHAKE) {
if (this.initialHandshake(byteBuffer)) {
this._connectionStatus = connection_status_1.ConnectionStatus.ACTIVE;
}
else {
logger_1.logger.warn(`Initial client handshake failed.`);
}
}
else {
this.decodeMessage(byteBuffer);
}
}
closeConnection() {
var _a;
this._connectionStatus = connection_status_1.ConnectionStatus.CLOSED;
if (((_a = this.socket) === null || _a === void 0 ? void 0 : _a.writable) && !this.socket.destroyed) {
this.socket.destroy();
}
this.connectionDestroyed();
}
error(error) {
if (error && typeof error === 'string') {
error = { message: error };
}
logger_1.logger.error('Socket destroyed due to error' + (error === null || error === void 0 ? void 0 : error.message) ? `: ${error.message}` : '.');
try {
this.closeConnection();
}
catch (closeConnectionError) {
logger_1.logger.error('Error closing server connection' +
(closeConnectionError === null || closeConnectionError === void 0 ? void 0 : closeConnectionError.message) ? `: ${closeConnectionError.message}` : '.');
}
}
get connectionStatus() {
return this._connectionStatus;
}
get connectionAlive() {
var _a;
return ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.writable) && !this.socket.destroyed;
}
}
exports.SocketServer = SocketServer;
//# sourceMappingURL=socket-server.js.map