feat: optimize framework add error catch(only log)

Signed-off-by: MiaoWoo <admin@yumc.pw>
backup
MiaoWoo 2020-03-24 13:27:11 +08:00
parent 5844ca9e7d
commit cbb73b451f
10 changed files with 191 additions and 99 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "@ms/websocket", "name": "@ms/websocket",
"version": "0.3.1", "version": "0.3.1",
"description": "MiaoScript api package", "description": "MiaoScript websocket package",
"keywords": [ "keywords": [
"miaoscript", "miaoscript",
"minecraft", "minecraft",
@ -27,9 +27,6 @@
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },
"dependencies": { "dependencies": {
"@ms/container": "^0.3.2", "@ms/nashorn": "^0.3.1"
"@ms/nashorn": "^0.3.1", }
"socket.io-parser": "^3.4.0"
},
"gitHead": "781524f83e52cad26d7c480513e3c525df867121"
} }

View File

@ -10,12 +10,14 @@ export abstract class TextWebSocketFrameHandlerAdapter {
acceptInboundMessage: (msg: any) => { acceptInboundMessage: (msg: any) => {
return TextWebSocketFrameMatcher.match(msg) return TextWebSocketFrameMatcher.match(msg)
}, },
channelRead0: this.channelRead0.bind(this) channelRead0: this.channelRead0.bind(this),
exceptionCaught: this.exceptionCaught.bind(this)
}) })
this._Handler = new TextWebSocketFrameHandlerAdapterImpl(); this._Handler = new TextWebSocketFrameHandlerAdapterImpl();
} }
abstract userEventTriggered(ctx: any, evt: any); abstract userEventTriggered(ctx: any, evt: any);
abstract channelRead0(ctx: any, msg: any); abstract channelRead0(ctx: any, msg: any);
abstract exceptionCaught(ctx: any, cause: Error);
getHandler() { getHandler() {
return this._Handler; return this._Handler;
} }

View File

@ -6,13 +6,12 @@ import { WebSocketHandler } from './websocket_handler'
import { NettyClient } from './client' import { NettyClient } from './client'
import { NettyWebSocketServerOptions } from './config' import { NettyWebSocketServerOptions } from './config'
class NettyWebSocketServer { class NettyWebSocketServer extends EventEmitter {
private event: EventEmitter
private pipeline: any; private pipeline: any;
private allClients: { [key: string]: NettyClient }; private allClients: { [key: string]: NettyClient };
constructor(pipeline: any, options: NettyWebSocketServerOptions) { constructor(pipeline: any, options: NettyWebSocketServerOptions) {
this.event = new EventEmitter(); super()
this.allClients = {}; this.allClients = {};
this.pipeline = pipeline; this.pipeline = pipeline;
let connectEvent = options.event; let connectEvent = options.event;
@ -24,25 +23,18 @@ class NettyWebSocketServer {
connectEvent.on(ServerEvent.connect, (ctx) => { connectEvent.on(ServerEvent.connect, (ctx) => {
let nettyClient = new NettyClient(this, ctx.channel()); let nettyClient = new NettyClient(this, ctx.channel());
this.allClients[nettyClient.id] = nettyClient; this.allClients[nettyClient.id] = nettyClient;
this.event.emit(ServerEvent.connect, nettyClient); this.emit(ServerEvent.connect, nettyClient);
}) })
connectEvent.on(ServerEvent.message, (ctx, msg) => { connectEvent.on(ServerEvent.message, (ctx, msg) => {
let channel = ctx.channel(); let channel = ctx.channel();
this.event.emit(ServerEvent.message, this.allClients[channel.id()], msg.text()) this.emit(ServerEvent.message, this.allClients[channel.id()], msg.text())
}) })
} }
close() {
disable() {
if (this.pipeline.names().contains(Keys.Detect)) { if (this.pipeline.names().contains(Keys.Detect)) {
this.pipeline.remove(Keys.Detect) this.pipeline.remove(Keys.Detect)
} }
Object.values(this.allClients).forEach(client => { Object.values(this.allClients).forEach(client => client.close())
client.close();
})
}
on(event: string, listener: (...args: any[]) => void) {
this.event.on(event, listener)
} }
} }

View File

@ -17,4 +17,7 @@ export class TextWebSocketFrameHandler extends TextWebSocketFrameHandlerAdapter
channelRead0(ctx: any, msg: any) { channelRead0(ctx: any, msg: any) {
this.event.emit(ServerEvent.message, ctx, msg) this.event.emit(ServerEvent.message, ctx, msg)
} }
exceptionCaught(ctx: any, cause: Error) {
console.ex(cause)
}
} }

View File

@ -2,14 +2,18 @@ import { EventEmitter } from 'events'
import { SocketIO } from './interfaces'; import { SocketIO } from './interfaces';
import { Namespace } from './namespace'; import { Namespace } from './namespace';
import { Parser } from './parser'; import { Parser } from './parser';
import { Socket } from './socket';
export class Adapter extends EventEmitter implements SocketIO.Adapter { export class Adapter extends EventEmitter implements SocketIO.Adapter {
nsp: SocketIO.Namespace; nsp: Namespace;
rooms: Rooms; rooms: Rooms;
sids: { [id: string]: { [room: string]: boolean; }; }; sids: { [id: string]: { [room: string]: boolean; }; };
parser: Parser parser: Parser
constructor(nsp: Namespace) { constructor(nsp: Namespace) {
super() super()
this.nsp = nsp;
this.rooms = new Rooms();
this.sids = {};
this.parser = nsp.server.parser; this.parser = nsp.server.parser;
} }
add(id: string, room: string, callback?: (err?: any) => void): void { add(id: string, room: string, callback?: (err?: any) => void): void {
@ -23,7 +27,7 @@ export class Adapter extends EventEmitter implements SocketIO.Adapter {
* @param {Function} callback * @param {Function} callback
* @api public * @api public
*/ */
addAll(id, rooms, fn) { addAll(id: string, rooms: string | any[], fn: { (err?: any): void; bind?: any; }) {
for (var i = 0; i < rooms.length; i++) { for (var i = 0; i < rooms.length; i++) {
var room = rooms[i]; var room = rooms[i];
this.sids[id] = this.sids[id] || {}; this.sids[id] = this.sids[id] || {};
@ -42,7 +46,6 @@ export class Adapter extends EventEmitter implements SocketIO.Adapter {
} }
callback && callback.bind(null, null) callback && callback.bind(null, null)
} }
delAll(id: string): void { delAll(id: string): void {
var rooms = this.sids[id]; var rooms = this.sids[id];
if (rooms) { if (rooms) {
@ -66,10 +69,10 @@ export class Adapter extends EventEmitter implements SocketIO.Adapter {
}; };
var ids = {}; var ids = {};
var self = this; var self = this;
var socket; var socket: Socket;
packet.nsp = this.nsp.name; packet.nsp = this.nsp.name;
let encodedPackets = this.parser.encode(packet) // let encodedPackets = this.parser.encode(packet)
if (rooms.length) { if (rooms.length) {
for (var i = 0; i < rooms.length; i++) { for (var i = 0; i < rooms.length; i++) {
var room = self.rooms[rooms[i]]; var room = self.rooms[rooms[i]];
@ -80,7 +83,7 @@ export class Adapter extends EventEmitter implements SocketIO.Adapter {
if (ids[id] || ~except.indexOf(id)) continue; if (ids[id] || ~except.indexOf(id)) continue;
socket = self.nsp.connected[id]; socket = self.nsp.connected[id];
if (socket) { if (socket) {
socket.packet(encodedPackets, packetOpts); socket.packet(packet, packetOpts);
ids[id] = true; ids[id] = true;
} }
} }
@ -91,7 +94,7 @@ export class Adapter extends EventEmitter implements SocketIO.Adapter {
if (self.sids.hasOwnProperty(id)) { if (self.sids.hasOwnProperty(id)) {
if (~except.indexOf(id)) continue; if (~except.indexOf(id)) continue;
socket = self.nsp.connected[id]; socket = self.nsp.connected[id];
if (socket) socket.packet(encodedPackets, packetOpts); if (socket) socket.packet(packet, packetOpts);
} }
} }
} }

View File

@ -9,6 +9,7 @@ import { PacketTypes, SubPacketTypes } from './types';
const parser = new Parser(); const parser = new Parser();
export class Client extends EventEmitter implements SocketIO.Client { export class Client extends EventEmitter implements SocketIO.Client {
id: string;
server: Server; server: Server;
conn: NettyClient; conn: NettyClient;
request: any; request: any;
@ -20,13 +21,11 @@ export class Client extends EventEmitter implements SocketIO.Client {
super(); super();
this.server = server; this.server = server;
this.conn = nettyClient; this.conn = nettyClient;
this.id = this.conn.id + '';
this.request = nettyClient.request; this.request = nettyClient.request;
this.sockets = {}; this.sockets = {};
this.nsps = {}; this.nsps = {};
} }
get id() {
return this.conn.id;
}
connect(name, query) { connect(name, query) {
if (this.server.nsps[name]) { if (this.server.nsps[name]) {
// console.debug(`connecting to namespace ${name}`); // console.debug(`connecting to namespace ${name}`);
@ -63,7 +62,7 @@ export class Client extends EventEmitter implements SocketIO.Client {
} }
}); });
} }
packet(packet: Packet) { packet(packet: Packet, opts?: any) {
this.conn.send(parser.encode(packet)) this.conn.send(parser.encode(packet))
} }
onclose(reason: string) { onclose(reason: string) {

View File

@ -83,7 +83,7 @@ class Server implements SocketIO.Server {
bind(srv: any): SocketIO.Server { bind(srv: any): SocketIO.Server {
throw new Error("Method not implemented."); throw new Error("Method not implemented.");
} }
onconnection(socket: any): SocketIO.Server { onconnection(socket: Client): SocketIO.Server {
this.allClients[socket.id] = socket; this.allClients[socket.id] = socket;
socket.packet({ socket.packet({
type: PacketTypes.OPEN, type: PacketTypes.OPEN,
@ -104,53 +104,47 @@ class Server implements SocketIO.Server {
return this.nsps[nsp]; return this.nsps[nsp];
} }
close(fn?: () => void): void { close(fn?: () => void): void {
throw new Error("Method not implemented."); for (let socket in this.sockets.sockets) {
this.sockets.sockets[socket].onclose()
}
this.nettyServer.close();
} }
on(event: "connection", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace; on(event: "connection", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace;
on(event: "connect", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace; on(event: "connect", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace;
on(event: string, listener: Function): SocketIO.Namespace; on(event: string, listener: Function): SocketIO.Namespace;
on(event: any, listener: any): SocketIO.Namespace { on(event: any, listener: any): SocketIO.Namespace {
this.event.on(event, listener); return this.sockets.on(event, listener);
return this.sockets;
} }
to(room: string): SocketIO.Namespace { to(room: string): SocketIO.Namespace {
throw new Error("Method not implemented."); return this.sockets.to(room);
} }
in(room: string): SocketIO.Namespace { in(room: string): SocketIO.Namespace {
throw new Error("Method not implemented."); return this.sockets.in(room);
} }
use(fn: (socket: SocketIO.Socket, fn: (err?: any) => void) => void): SocketIO.Namespace { use(fn: (socket: SocketIO.Socket, fn: (err?: any) => void) => void): SocketIO.Namespace {
throw new Error("Method not implemented."); return this.sockets.use(fn);
} }
emit(event: string, ...args: any[]): SocketIO.Namespace { emit(event: string, ...args: any[]): SocketIO.Namespace {
this.sockets.emit(event, ...args); // @ts-ignore
return this.sockets; return this.sockets.emit(event, ...args);
} }
send(...args: any[]): SocketIO.Namespace { send(...args: any[]): SocketIO.Namespace {
this.sockets.send(...args); return this.sockets.send(...args);
return this.sockets;
} }
write(...args: any[]): SocketIO.Namespace { write(...args: any[]): SocketIO.Namespace {
this.sockets.write(...args); return this.sockets.write(...args);
return this.sockets;
} }
clients(...args: any[]): SocketIO.Namespace { clients(...args: any[]): SocketIO.Namespace {
this.sockets.clients(args[0]); return this.sockets.clients(args[0]);
return this.sockets;
} }
compress(...args: any[]): SocketIO.Namespace { compress(...args: any[]): SocketIO.Namespace {
throw new Error("Method not implemented."); return this.sockets.compress(args[0])
} }
// =============================== // ===============================
checkNamespace(name, query, fn) { checkNamespace(name, query, fn) {
fn(false); fn(false);
}; };
disable() {
this.nettyServer.disable();
}
private initNettyServer(pipeline, options) { private initNettyServer(pipeline, options) {
this.nettyServer = new NettyWebSocketServer(pipeline, { this.nettyServer = new NettyWebSocketServer(pipeline, {
event: new EventEmitter(), event: new EventEmitter(),

View File

@ -17,12 +17,23 @@ export class Namespace extends EventEmitter implements SocketIO.Namespace {
adapter: SocketIO.Adapter; adapter: SocketIO.Adapter;
json: SocketIO.Namespace; json: SocketIO.Namespace;
fns: any[];
ids: number;
rooms: string[];
flags: { [key: string]: boolean };
private events = ['connect', 'connection', 'newListener']
constructor(name: string, server: Server) { constructor(name: string, server: Server) {
super(); super();
this.name = name; this.name = name;
this.server = server; this.server = server;
this.sockets = {}; this.sockets = {};
this.connected = {}; this.connected = {};
this.fns = [];
this.ids = 0;
this.rooms = [];
this.flags = {};
this.adapter = new Adapter(this); this.adapter = new Adapter(this);
} }
initAdapter() { initAdapter() {
@ -43,23 +54,55 @@ export class Namespace extends EventEmitter implements SocketIO.Namespace {
delete this.sockets[client.id]; delete this.sockets[client.id];
} }
use(fn: (socket: SocketIO.Socket, fn: (err?: any) => void) => void): SocketIO.Namespace { use(fn: (socket: SocketIO.Socket, fn: (err?: any) => void) => void): SocketIO.Namespace {
// TODO throw new Error("Method not implemented.");
return this;
} }
to(room: string): SocketIO.Namespace { to(room: string): SocketIO.Namespace {
// TODO if (!~this.rooms.indexOf(room)) this.rooms.push(room);
return this; return this;
} }
in(room: string): SocketIO.Namespace { in(room: string): SocketIO.Namespace {
return this.to(room); return this.to(room);
} }
send(...args: any[]): SocketIO.Namespace { send(...args: any[]): SocketIO.Namespace {
// TODO super.emit('message', ...args)
return this; return this;
} }
write(...args: any[]): SocketIO.Namespace { write(...args: any[]): SocketIO.Namespace {
return this.send(...args); return this.send(...args);
} }
emit(event: string, ...args: any[]): boolean {
if (~this.events.indexOf(event)) {
super.emit(event, ...args);
// @ts-ignore
return this;
}
// set up packet object
var packet = {
type: (this.flags.binary !== undefined ? this.flags.binary : this.hasBin(args)) ? SubPacketTypes.BINARY_EVENT : SubPacketTypes.EVENT,
data: args
}
if ('function' == typeof args[args.length - 1]) {
throw new Error('Callbacks are not supported when broadcasting');
}
var rooms = this.rooms.slice(0);
var flags = Object.assign({}, this.flags);
// reset flags
this.rooms = [];
this.flags = {};
this.adapter.broadcast(packet, {
rooms: rooms,
flags: flags
});
// @ts-ignore
return this;
}
hasBin(args: any[]) {
return false;
}
clients(fn: Function): SocketIO.Namespace { clients(fn: Function): SocketIO.Namespace {
return fn(Object.values(this.sockets)) return fn(Object.values(this.sockets))
} }

View File

@ -3,8 +3,9 @@ import { PacketTypes, SubPacketTypes } from "./types";
export class Parser { export class Parser {
encode(packet: Packet): string { encode(packet: Packet): string {
let origin = JSON.stringify(packet)
// first is type // first is type
var str = '' + packet.type; let str = '' + packet.type;
if (packet.type == PacketTypes.PONG) { if (packet.type == PacketTypes.PONG) {
if (packet.data) { str += packet.data }; if (packet.data) { str += packet.data };
return str; return str;
@ -26,18 +27,19 @@ export class Parser {
str += packet.id; str += packet.id;
} }
if (packet.sub_type == SubPacketTypes.EVENT) { if (packet.sub_type == SubPacketTypes.EVENT) {
if (packet.name == undefined) { throw new Error(`SubPacketTypes.EVENT name can't be empty!`) }
packet.data = [packet.name, packet.data] packet.data = [packet.name, packet.data]
} }
// json data // json data
if (null != packet.data) { if (null != packet.data) {
var payload = this.tryStringify(packet.data); let payload = this.tryStringify(packet.data);
if (payload !== false) { if (payload !== false) {
str += payload; str += payload;
} else { } else {
return '4"encode error"' return '4"encode error"'
} }
} }
console.debug(`encoded ${JSON.stringify(packet)} as ${str}`); console.debug(`encoded ${origin} as ${str}`);
return str; return str;
} }
tryStringify(str) { tryStringify(str) {
@ -48,14 +50,14 @@ export class Parser {
} }
} }
decode(str: string): Packet { decode(str: string): Packet {
var i = 0; let i = 0;
// ignore parse binary // ignore parse binary
// if ((frame.getByte(0) == 'b' && frame.getByte(1) == '4') // if ((frame.getByte(0) == 'b' && frame.getByte(1) == '4')
// || frame.getByte(0) == 4 || frame.getByte(0) == 1) { // || frame.getByte(0) == 4 || frame.getByte(0) == 1) {
// return parseBinary(head, frame); // return parseBinary(head, frame);
// } // }
// look up type // look up type
var p: Packet = { let p: Packet = {
type: Number(str.charAt(i)) type: Number(str.charAt(i))
}; };
if (null == PacketTypes[p.type]) { if (null == PacketTypes[p.type]) {
@ -77,7 +79,7 @@ export class Parser {
} }
// look up attachments if type binary // look up attachments if type binary
if ([SubPacketTypes.BINARY_ACK, SubPacketTypes.BINARY_EVENT].includes(p.sub_type)) { if ([SubPacketTypes.BINARY_ACK, SubPacketTypes.BINARY_EVENT].includes(p.sub_type)) {
var buf = ''; let buf = '';
while (str.charAt(++i) !== '-') { while (str.charAt(++i) !== '-') {
buf += str.charAt(i); buf += str.charAt(i);
if (i == str.length) break; if (i == str.length) break;
@ -92,7 +94,7 @@ export class Parser {
if ('/' === str.charAt(i + 1)) { if ('/' === str.charAt(i + 1)) {
p.nsp = ''; p.nsp = '';
while (++i) { while (++i) {
var c = str.charAt(i); let c = str.charAt(i);
if (',' === c) break; if (',' === c) break;
p.nsp += c; p.nsp += c;
if (i === str.length) break; if (i === str.length) break;
@ -102,11 +104,11 @@ export class Parser {
} }
// look up id // look up id
var next = str.charAt(i + 1); let next = str.charAt(i + 1);
if ('' !== next && Number.isNaN(Number(next))) { if ('' !== next && Number.isNaN(Number(next))) {
var id = '' let id = ''
while (++i) { while (++i) {
var c = str.charAt(i); let c = str.charAt(i);
if (null == c || Number.isNaN(Number(c))) { if (null == c || Number.isNaN(Number(c))) {
--i; --i;
break; break;
@ -128,8 +130,8 @@ export class Parser {
// look up json data // look up json data
if (str.charAt(++i)) { if (str.charAt(++i)) {
var payload = this.tryParse(str.substr(i)); let payload = this.tryParse(str.substr(i));
var isPayloadValid = payload !== false && (p.sub_type == SubPacketTypes.ERROR || Array.isArray(payload)); let isPayloadValid = payload !== false && (p.sub_type == SubPacketTypes.ERROR || Array.isArray(payload));
if (isPayloadValid) { if (isPayloadValid) {
p.name = payload[0]; p.name = payload[0];
p.data = payload[1]; p.data = payload[1];

View File

@ -7,8 +7,6 @@ import { Client } from './client';
import { Namespace } from './namespace'; import { Namespace } from './namespace';
export class Socket extends EventEmitter implements SocketIO.Socket { export class Socket extends EventEmitter implements SocketIO.Socket {
private event: EventEmitter;
nsp: Namespace; nsp: Namespace;
server: SocketIO.Server; server: SocketIO.Server;
adapter: SocketIO.Adapter; adapter: SocketIO.Adapter;
@ -21,12 +19,19 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
connected: boolean; connected: boolean;
disconnected: boolean; disconnected: boolean;
handshake: SocketIO.Handshake; handshake: SocketIO.Handshake;
json: SocketIO.Socket;
volatile: SocketIO.Socket;
broadcast: SocketIO.Socket;
fns: any[]; fns: any[];
flags: { [key: string]: boolean };
_rooms: string[]; _rooms: string[];
private events = [
'error',
'connect',
'disconnect',
'disconnecting',
'newListener',
'removeListener'
]
constructor(nsp: Namespace, client: Client, query = {}) { constructor(nsp: Namespace, client: Client, query = {}) {
super(); super();
this.nsp = nsp; this.nsp = nsp;
@ -42,10 +47,26 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
this.disconnected = false; this.disconnected = false;
// this.handshake = this.buildHandshake(query); // this.handshake = this.buildHandshake(query);
this.fns = []; this.fns = [];
// this.flags = {}; this.flags = {};
this._rooms = []; this._rooms = [];
}
this.event = new EventEmitter(); get json() {
this.flags.json = true;
return this
}
get volatile() {
this.flags.volatile = true;
return this
}
get broadcast() {
this.flags.broadcast = true;
return this
}
get local() {
this.flags.local = true;
return this
} }
to(room: string): SocketIO.Socket { to(room: string): SocketIO.Socket {
@ -95,11 +116,10 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
throw new Error("Method not implemented."); throw new Error("Method not implemented.");
} }
error(err: any): void { error(err: any): void {
throw new Error("Method not implemented."); this.packet({ type: PacketTypes.MESSAGE, sub_type: SubPacketTypes.ERROR, data: err });
} }
// ========================================== // ==========================================
buildHandshake(query): SocketIO.Handshake { buildHandshake(query): SocketIO.Handshake {
let requestQuery = this.request.uri(); let requestQuery = this.request.uri();
return { return {
@ -113,29 +133,61 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
query: Object.assign(query, requestQuery) query: Object.assign(query, requestQuery)
} }
} }
on(event: string, callback: (...args: any[]) => void) {
this.event.on(event, callback);
return this
}
emit(event: string, ...args: any[]): boolean { emit(event: string, ...args: any[]): boolean {
this.packet({ if (~this.events.indexOf(event)) {
super.emit(event, ...args);
// @ts-ignore
return this;
}
let packet: Packet = {
type: PacketTypes.MESSAGE, type: PacketTypes.MESSAGE,
sub_type: SubPacketTypes.EVENT, sub_type: (this.flags.binary !== undefined ? this.flags.binary : this.hasBin(args)) ? SubPacketTypes.BINARY_EVENT : SubPacketTypes.EVENT,
name: event, name: event,
data: args[0] data: args[0]
}) }
return true;
// access last argument to see if it's an ACK callback
if (typeof args[args.length - 1] === 'function') {
if (this._rooms.length || this.flags.broadcast) {
throw new Error('Callbacks are not supported when broadcasting');
}
// debug('emitting packet with ack id %d', this.nsp.ids);
this.acks[this.nsp.ids] = args.pop();
packet.id = this.nsp.ids++;
}
let rooms = this._rooms.slice(0);
let flags = Object.assign({}, this.flags);
// reset flags
this._rooms = [];
this.flags = {};
if (rooms.length || flags.broadcast) {
this.adapter.broadcast(packet, {
except: [this.id],
rooms: rooms,
flags: flags
});
} else {
// dispatch packet
this.packet(packet, flags);
}
// @ts-ignore
return this;
} }
packet(packet: Packet) { packet(packet: Packet, opts?: any) {
packet.nsp = this.nsp.name; packet.nsp = this.nsp.name;
this.client.packet(packet); opts = opts || {};
opts.compress = false !== opts.compress;
this.client.packet(packet, opts);
} }
onconnect() { onconnect() {
this.nsp.connected[this.id] = this; this.nsp.connected[this.id] = this;
this.client.sockets[this.id] = this; this.client.sockets[this.id] = this;
this.join(this.id); this.join(this.id);
// var skip = this.nsp.name === '/' && this.nsp.fns.length === 0; // let skip = this.nsp.name === '/' && this.nsp.fns.length === 0;
// if (skip) { // if (skip) {
// debug('packet already sent in initial handshake'); // debug('packet already sent in initial handshake');
// } else { // } else {
@ -145,7 +197,7 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
}); });
// } // }
} }
onclose(reason) { onclose(reason?: string) {
if (!this.connected) return this; if (!this.connected) return this;
// debug('closing socket - reason %s', reason); // debug('closing socket - reason %s', reason);
this.emit('disconnecting', reason); this.emit('disconnecting', reason);
@ -156,7 +208,7 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
this.disconnected = true; this.disconnected = true;
delete this.nsp.connected[this.id]; delete this.nsp.connected[this.id];
this.emit('disconnect', reason); this.emit('disconnect', reason);
}; }
onpacket(packet: Packet) { onpacket(packet: Packet) {
switch (packet.sub_type) { switch (packet.sub_type) {
case SubPacketTypes.EVENT: case SubPacketTypes.EVENT:
@ -178,11 +230,16 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
this.onerror(new Error(packet.data)); this.onerror(new Error(packet.data));
} }
} }
onerror(error: Error) { onerror(err: Error) {
if (this.listeners('error').length) {
this.emit('error', err);
} else {
console.error('Missing error handler on `socket`.');
console.error(err.stack);
}
} }
ondisconnect() { ondisconnect() {
this.onclose this.onclose('client namespace disconnect')
} }
onevent(packet: Packet) { onevent(packet: Packet) {
// console.debug('emitting event %j', args); // console.debug('emitting event %j', args);
@ -191,9 +248,9 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
this.dispatch(packet, this.ack(packet.id)) this.dispatch(packet, this.ack(packet.id))
} }
this.dispatch(packet); this.dispatch(packet);
}; }
ack(id: number) { ack(id: number) {
var sent = false; let sent = false;
return (...args: any[]) => { return (...args: any[]) => {
if (sent) return; if (sent) return;
this.packet({ this.packet({
@ -206,7 +263,7 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
} }
} }
onack(packet: Packet) { onack(packet: Packet) {
var ack = this.acks[packet.id]; let ack = this.acks[packet.id];
if ('function' == typeof ack) { if ('function' == typeof ack) {
// debug('calling ack %s with %j', packet.id, packet.data); // debug('calling ack %s with %j', packet.id, packet.data);
ack.apply(this, packet.data); ack.apply(this, packet.data);
@ -217,7 +274,7 @@ export class Socket extends EventEmitter implements SocketIO.Socket {
} }
dispatch(packet: Packet, ack?: Function) { dispatch(packet: Packet, ack?: Function) {
if (ack) { this.acks[packet.id] = ack; } if (ack) { this.acks[packet.id] = ack; }
this.event.emit(packet.name, packet.data) super.emit(packet.name, packet.data)
} }
private hasBin(obj: any) { private hasBin(obj: any) {
return false; return false;