nxkit
Version:
This is a collection of tools, independent of any other libraries
197 lines (196 loc) • 7.16 kB
JavaScript
"use strict";
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2015, xuewen.chu
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of xuewen.chu nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL xuewen.chu BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
const util_1 = require("../../util");
const path_1 = require("../../path");
const errno_1 = require("../../errno");
const data_1 = require("../data");
const _conv_1 = require("../_conv");
__export(require("../_conv"));
const event_1 = require("../../event");
var USE_GZIP_DATA = false;
/**
* @class WSConversation
*/
class WSConversation extends _conv_1.ConversationBasic {
constructor(path) {
super();
this.m_connecting = false; // 是否尝试连接中
this.m_signer = null;
this.m_autoReconnect = 0; // reconnect time
this.onError = new event_1.EventNoticer('Error', this);
path = path || util_1.default.config.web_service || 'ws://localhost';
util_1.default.assert(path, 'Server path is not correct');
path = path_1.default.resolve(path);
this.m_url = new path_1.URL(path.replace(/^http/, 'ws'));
}
get autoReconnect() {
return this.m_autoReconnect;
}
set autoReconnect(value) {
this.m_autoReconnect = Math.min(Math.max(0, Number(value) || 0), 5e3);
}
get keepAliveTime() {
return this.m_KEEP_ALIVE_TIME;
}
set keepAliveTime(value) {
this.m_KEEP_ALIVE_TIME = Math.max(5e3, Number(value) || _conv_1.KEEP_ALIVE_TIME);
this._keepAlive();
}
get url() {
return this.m_url;
}
_keepAlive() {
this._clearKeepAlive();
if (this.m_isOpen) {
this.m_IntervalId = setInterval(() => {
if (this.keepAliveTime * 2 + this.lastPacketTime < Date.now()) {
this._error(Error.new(errno_1.default.ERR_WS_CLIENT_NO_ALIVE));
this.close();
}
else {
this.ping();
}
}, util_1.default.random(0, Math.floor(this.m_KEEP_ALIVE_TIME / 10)) + this.m_KEEP_ALIVE_TIME);
}
}
_clearKeepAlive() {
if (this.m_IntervalId) {
clearInterval(this.m_IntervalId);
this.m_IntervalId = 0;
}
}
_autoReconnect(reason) {
if (!this.m_isOpen && this.m_autoReconnect) { // keep connect
util_1.default.sleep(this.m_autoReconnect).then(() => {
console.log(`Reconnect ${reason} Clo.. ${this.m_url.href}`);
this.connect();
});
}
}
setGzip(value) {
util_1.default.assert(!this.m_isOpen, 'Can only be set before opening');
this.m_isGzip = !!value;
}
bindServices(services) {
throw Error.new(errno_1.default.ERR_METHOD_UNREALIZED);
}
/**
* @fun bind # 绑定
* @arg client {Client}
*/
bind(client) {
var name = client.name;
if (name in this.m_handles) {
throw new Error('No need to repeat binding');
}
else {
if (!this.m_default_service)
this.m_default_service = name;
this.m_handles[name] = client;
this.m_services_count++;
if (this.m_isOpen) {
this.sendFormatData({ service: name, type: data_1.Types.T_BIND });
}
else {
util_1.default.nextTick(() => this.connect()); // 还没有打开连接,下一帧开始尝试连接
}
}
}
_open() {
util_1.default.assert(!this.m_isOpen);
util_1.default.assert(this.m_connecting);
// await utils.sleep(1e2); // 100ms
this.m_isOpen = true;
this.m_connecting = false;
this.m_last_packet_time = Date.now();
this.m_overflow = false;
this.onOpen.trigger({});
this._keepAlive();
}
_error(err) {
if (this.m_connecting)
this.close();
util_1.default.nextTick(() => this.onError.trigger(err));
this._autoReconnect('Error');
}
get signer() {
return this.m_signer;
}
set signer(value) {
this.m_signer = value;
}
/**
* @rewrite
* @func getRequestHeaders
*/
getRequestHeaders() {
return {};
}
/**
* @fun close # close conversation connection
*/
close() {
var _a;
if (this.m_connecting) {
// console.log('**** close conversation connection');
this.m_connecting = false;
}
if (this.m_isOpen) {
this.m_isOpen = false;
this.m_token = '';
this._clearKeepAlive();
this.onClose.trigger({});
this._autoReconnect('Close');
console.log('CLI Conversation Close', (_a = this.m_url) === null || _a === void 0 ? void 0 : _a.href);
}
}
/**
* @fun connect # connercion server
*/
connect() {
var _a;
if (!this.m_isOpen && !this.m_connecting) {
util_1.default.assert(this.m_default_service, 'connection must bind service'); // 连接必需要绑定服务才能使用
console.log('Connection..', (_a = this.m_url) === null || _a === void 0 ? void 0 : _a.href, this.m_connecting);
this.m_connecting = true;
this.initialize();
}
}
}
exports.WSConversation = WSConversation;
exports.default = {
get USE_GZIP_DATA() { return USE_GZIP_DATA; },
set USE_GZIP_DATA(value) { USE_GZIP_DATA = value; },
};