shardy
Version:
Framework for online games and applications on Node.js
134 lines • 5.41 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Protocol = exports.ProtocolState = void 0;
const Block_1 = require("./Block");
const Logger_1 = require("./Logger");
const Tools_1 = require("./Tools");
const Transport_1 = require("./Transport");
const LOG_TAG = Tools_1.Tools.getTag(module);
var ProtocolState;
(function (ProtocolState) {
ProtocolState[ProtocolState["Start"] = 0] = "Start";
ProtocolState[ProtocolState["Handshake"] = 1] = "Handshake";
ProtocolState[ProtocolState["Work"] = 2] = "Work";
ProtocolState[ProtocolState["Closed"] = 3] = "Closed";
})(ProtocolState || (exports.ProtocolState = ProtocolState = {}));
class Protocol {
constructor(connection, log) {
this.connection = connection;
this.log = log;
this.onBlock = () => { };
this.onDisconnect = () => { };
this.state = ProtocolState.Start;
this.transport = new Transport_1.Transport(this.connection, this.log);
this.transport.onData = (data) => this.onData(data);
this.transport.onDisconnect = () => this.onClose();
}
dispatch(type, body) {
if (this.state === ProtocolState.Closed) {
this.log.warn(`[${LOG_TAG}] send data to closed protocol`, Logger_1.LoggerScope.Debug);
return;
}
body = body ? body : Buffer.alloc(0);
this.log.info(`[${LOG_TAG}] dispatch type: ${type}, body: ${body}`, Logger_1.LoggerScope.Debug);
const data = Block_1.Block.encode(type, body);
this.transport.dispatch(data);
}
send(body) {
this.log.info(`[${LOG_TAG}] send data: ${body}`, Logger_1.LoggerScope.Debug);
this.dispatch(Block_1.BlockType.Data, body);
}
heartbeat() {
this.log.info(`[${LOG_TAG}] send heartbeat`, Logger_1.LoggerScope.Debug);
this.dispatch(Block_1.BlockType.Heartbeat);
}
handshake(body) {
this.log.info(`[${LOG_TAG}] send handshake`, Logger_1.LoggerScope.Debug);
this.state = ProtocolState.Handshake;
this.dispatch(Block_1.BlockType.Handshake, body);
}
acknowledge(body) {
this.log.info(`[${LOG_TAG}] send acknowledge`, Logger_1.LoggerScope.Debug);
this.dispatch(Block_1.BlockType.HandshakeAcknowledgement, body);
}
kick(reason) {
this.log.info(`[${LOG_TAG}] send kick`, Logger_1.LoggerScope.Debug);
this.dispatch(Block_1.BlockType.Kick, Buffer.from(reason.toString()));
}
disconnect() {
this.state = ProtocolState.Closed;
this.log.info(`[${LOG_TAG}] disconnect`, Logger_1.LoggerScope.Debug);
this.transport.close();
}
onClose() {
this.state = ProtocolState.Closed;
this.onDisconnect();
}
onData(data) {
if (this.state === ProtocolState.Closed) {
this.log.warn(`[${LOG_TAG}] received data to closed protocol`, Logger_1.LoggerScope.Debug);
return;
}
const block = Block_1.Block.decode(data);
if (!Block_1.Block.check(block.type)) {
this.catchBlockForState(block.type);
return;
}
this.log.info(`[${LOG_TAG}] received block: ${block.type}, data: ${block.body}, state: ${this.state}`, Logger_1.LoggerScope.Debug);
switch (this.state) {
case ProtocolState.Work:
switch (block.type) {
case Block_1.BlockType.Heartbeat:
case Block_1.BlockType.Kick:
case Block_1.BlockType.Data:
this.onBlock(block);
break;
default:
this.catchBlockForState(block.type);
break;
}
break;
case ProtocolState.Start:
switch (block.type) {
case Block_1.BlockType.Heartbeat:
this.onBlock(block);
break;
case Block_1.BlockType.Handshake:
this.onBlock(block);
this.state = ProtocolState.Handshake;
break;
default:
this.catchBlockForState(block.type);
break;
}
break;
case ProtocolState.Handshake:
switch (block.type) {
case Block_1.BlockType.HandshakeAcknowledgement:
this.state = ProtocolState.Work;
this.onBlock(block);
break;
case Block_1.BlockType.Heartbeat:
case Block_1.BlockType.Kick:
this.onBlock(block);
break;
default:
this.catchBlockForState(block.type);
break;
}
break;
default:
break;
}
}
catchBlockForState(type) {
this.log.warn(`[${LOG_TAG}] received invalid block type: ${type}, state: ${this.state}`, Logger_1.LoggerScope.Debug);
}
destroy() {
this.log.info(`[${LOG_TAG}] destroy`, Logger_1.LoggerScope.Debug);
this.state = ProtocolState.Closed;
this.transport.destroy();
}
}
exports.Protocol = Protocol;
//# sourceMappingURL=Protocol.js.map