feat: add adapter and socket
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
ace2c48ae2
commit
f4b461409b
@ -1,26 +1,29 @@
|
||||
import { EventEmitter } from 'events'
|
||||
import { SocketIO } from 'socket-io/interfaces';
|
||||
|
||||
const TextWebSocketFrame = Java.type('io.netty.handler.codec.http.websocketx.TextWebSocketFrame')
|
||||
|
||||
export class NettyClient {
|
||||
private event: EventEmitter
|
||||
|
||||
export class NettyClient extends EventEmitter implements SocketIO.EngineSocket {
|
||||
private _id: string;
|
||||
private channel: any
|
||||
constructor(channel: any) {
|
||||
|
||||
server: any;
|
||||
readyState: string;
|
||||
remoteAddress: string;
|
||||
upgraded: boolean;
|
||||
request: any;
|
||||
transport: any;
|
||||
|
||||
constructor(server: any, channel: any) {
|
||||
super();
|
||||
this.server = server;
|
||||
this.channel = channel;
|
||||
this._id = channel.id();
|
||||
this.event = new EventEmitter();
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this._id;
|
||||
}
|
||||
on(event: string, callback: (...args: any[]) => void) {
|
||||
this.event.on(event, callback);
|
||||
}
|
||||
emit(event: string, text: string) {
|
||||
this.event.emit(event, text);
|
||||
}
|
||||
send(text: string) {
|
||||
this.channel.writeAndFlush(new TextWebSocketFrame(text))
|
||||
}
|
||||
|
6
packages/websocket/src/server/config.ts
Normal file
6
packages/websocket/src/server/config.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { EventEmitter } from 'events'
|
||||
|
||||
export interface NettyWebSocketServerOptions {
|
||||
event: EventEmitter,
|
||||
path?: string;
|
||||
}
|
@ -4,10 +4,7 @@ import { ServerEvent, Keys } from './constants'
|
||||
import { WebSocketDetect } from './websocket_detect'
|
||||
import { WebSocketHandler } from './websocket_handler'
|
||||
import { NettyClient } from './client'
|
||||
|
||||
interface NettyWebSocketServerOptions {
|
||||
path?: string;
|
||||
}
|
||||
import { NettyWebSocketServerOptions } from './config'
|
||||
|
||||
class NettyWebSocketServer {
|
||||
private event: EventEmitter
|
||||
@ -18,20 +15,20 @@ class NettyWebSocketServer {
|
||||
this.event = new EventEmitter();
|
||||
this.allClients = {};
|
||||
this.pipeline = pipeline;
|
||||
let connectEvent = new EventEmitter();
|
||||
let connectEvent = options.event;
|
||||
this.pipeline.addFirst(Keys.Detect, new WebSocketDetect(connectEvent).getHandler())
|
||||
connectEvent.on(ServerEvent.detect, (ctx, channel) => {
|
||||
channel.pipeline().addFirst(Keys.Handler, new WebSocketHandler(connectEvent).getHandler())
|
||||
channel.pipeline().addFirst(Keys.Handler, new WebSocketHandler(options).getHandler())
|
||||
ctx.fireChannelRead(channel)
|
||||
})
|
||||
connectEvent.on(ServerEvent.connect, (ctx) => {
|
||||
let nettyClient = new NettyClient(ctx.channel());
|
||||
let nettyClient = new NettyClient(this, ctx.channel());
|
||||
this.allClients[nettyClient.id] = nettyClient;
|
||||
this.event.emit(ServerEvent.connect, nettyClient);
|
||||
})
|
||||
connectEvent.on(ServerEvent.message, (ctx, msg) => {
|
||||
let channel = ctx.channel();
|
||||
this.allClients[channel.id()]?.emit(ServerEvent.message, msg.text())
|
||||
this.event.emit(ServerEvent.message, this.allClients[channel.id()], msg.text())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { TextWebSocketFrameHandlerAdapter } from '../netty'
|
||||
import { EventEmitter } from 'events'
|
||||
import { ServerEvent } from './constants'
|
||||
import { NettyWebSocketServerOptions } from './config';
|
||||
|
||||
export class TextWebSocketFrameHandler extends TextWebSocketFrameHandlerAdapter {
|
||||
private event: EventEmitter;
|
||||
constructor(event: EventEmitter) {
|
||||
constructor(options: NettyWebSocketServerOptions) {
|
||||
super()
|
||||
this.event = event;
|
||||
this.event = options.event;
|
||||
}
|
||||
userEventTriggered(ctx: any, evt: any) {
|
||||
if (evt == 'HANDSHAKE_COMPLETE') {
|
||||
|
@ -4,6 +4,7 @@ import { Keys } from './constants'
|
||||
import { WebSocketHandlerAdapter } from "../netty"
|
||||
import { HttpRequestHandler } from './httprequest'
|
||||
import { TextWebSocketFrameHandler } from './text_websocket_frame'
|
||||
import { NettyWebSocketServerOptions } from './config'
|
||||
|
||||
const CharsetUtil = Java.type('io.netty.util.CharsetUtil')
|
||||
|
||||
@ -13,10 +14,10 @@ const HttpObjectAggregator = Java.type('io.netty.handler.codec.http.HttpObjectAg
|
||||
const WebSocketServerProtocolHandler = Java.type('io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler')
|
||||
|
||||
export class WebSocketHandler extends WebSocketHandlerAdapter {
|
||||
private event: EventEmitter;
|
||||
constructor(event: EventEmitter) {
|
||||
private options: NettyWebSocketServerOptions;
|
||||
constructor(options: NettyWebSocketServerOptions) {
|
||||
super()
|
||||
this.event = event;
|
||||
this.options = options;
|
||||
}
|
||||
channelRead(ctx: any, msg: any) {
|
||||
msg.markReaderIndex()
|
||||
@ -32,8 +33,8 @@ export class WebSocketHandler extends WebSocketHandlerAdapter {
|
||||
pipeline.addLast('chunk', new ChunkedWriteHandler())
|
||||
pipeline.addLast('httpobj', new HttpObjectAggregator(64 * 1024))
|
||||
pipeline.addLast('http_request', new HttpRequestHandler().getHandler())
|
||||
pipeline.addLast('websocket', new WebSocketServerProtocolHandler("/ws", true))
|
||||
pipeline.addLast('websocket_handler', new TextWebSocketFrameHandler(this.event).getHandler())
|
||||
pipeline.addLast('websocket', new WebSocketServerProtocolHandler(this.options.path, true))
|
||||
pipeline.addLast('websocket_handler', new TextWebSocketFrameHandler(this.options).getHandler())
|
||||
}
|
||||
pipeline.remove(Keys.Handler)
|
||||
msg.resetReaderIndex()
|
||||
|
124
packages/websocket/src/socket-io/adapter.ts
Normal file
124
packages/websocket/src/socket-io/adapter.ts
Normal file
@ -0,0 +1,124 @@
|
||||
import { EventEmitter } from 'events'
|
||||
import { SocketIO } from './interfaces';
|
||||
import { Namespace } from './namespace';
|
||||
import { Parser } from './parser';
|
||||
|
||||
export class Adapter extends EventEmitter implements SocketIO.Adapter {
|
||||
nsp: SocketIO.Namespace;
|
||||
rooms: Rooms;
|
||||
sids: { [id: string]: { [room: string]: boolean; }; };
|
||||
parser: Parser
|
||||
constructor(nsp: Namespace) {
|
||||
super()
|
||||
this.parser = nsp.server.parser;
|
||||
}
|
||||
add(id: string, room: string, callback?: (err?: any) => void): void {
|
||||
return this.addAll(id, [room], callback);
|
||||
}
|
||||
/**
|
||||
* Adds a socket to a list of room.
|
||||
*
|
||||
* @param {String} socket id
|
||||
* @param {String} rooms
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
addAll(id, rooms, fn) {
|
||||
for (var i = 0; i < rooms.length; i++) {
|
||||
var room = rooms[i];
|
||||
this.sids[id] = this.sids[id] || {};
|
||||
this.sids[id][room] = true;
|
||||
this.rooms[room] = this.rooms[room] || new Room();
|
||||
this.rooms[room].add(id);
|
||||
}
|
||||
fn && fn.bind(null, null)
|
||||
};
|
||||
del(id: string, room: string, callback?: (err?: any) => void): void {
|
||||
if (this.sids[id]) delete this.sids[id][room];
|
||||
|
||||
if (this.rooms.hasOwnProperty(room)) {
|
||||
this.rooms[room].del(id);
|
||||
if (this.rooms[room].length === 0) delete this.rooms[room];
|
||||
}
|
||||
callback && callback.bind(null, null)
|
||||
}
|
||||
|
||||
delAll(id: string): void {
|
||||
var rooms = this.sids[id];
|
||||
if (rooms) {
|
||||
for (var room in rooms) {
|
||||
if (this.rooms.hasOwnProperty(room)) {
|
||||
this.rooms[room].del(id);
|
||||
if (this.rooms[room].length === 0) delete this.rooms[room];
|
||||
}
|
||||
}
|
||||
}
|
||||
delete this.sids[id];
|
||||
}
|
||||
broadcast(packet: any, opts: { rooms?: string[]; except?: string[]; flags?: { [flag: string]: boolean; }; }): void {
|
||||
var rooms = opts.rooms || [];
|
||||
var except = opts.except || [];
|
||||
var flags = opts.flags || {};
|
||||
var packetOpts = {
|
||||
preEncoded: true,
|
||||
volatile: flags.volatile,
|
||||
compress: flags.compress
|
||||
};
|
||||
var ids = {};
|
||||
var self = this;
|
||||
var socket;
|
||||
|
||||
packet.nsp = this.nsp.name;
|
||||
let encodedPackets = this.parser.encode(packet)
|
||||
if (rooms.length) {
|
||||
for (var i = 0; i < rooms.length; i++) {
|
||||
var room = self.rooms[rooms[i]];
|
||||
if (!room) continue;
|
||||
var sockets = room.sockets;
|
||||
for (var id in sockets) {
|
||||
if (sockets.hasOwnProperty(id)) {
|
||||
if (ids[id] || ~except.indexOf(id)) continue;
|
||||
socket = self.nsp.connected[id];
|
||||
if (socket) {
|
||||
socket.packet(encodedPackets, packetOpts);
|
||||
ids[id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var id in self.sids) {
|
||||
if (self.sids.hasOwnProperty(id)) {
|
||||
if (~except.indexOf(id)) continue;
|
||||
socket = self.nsp.connected[id];
|
||||
if (socket) socket.packet(encodedPackets, packetOpts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Rooms implements SocketIO.Rooms {
|
||||
[room: string]: Room;
|
||||
}
|
||||
|
||||
class Room implements SocketIO.Room {
|
||||
sockets: { [id: string]: boolean; };
|
||||
length: number;
|
||||
constructor() {
|
||||
this.sockets = {};
|
||||
this.length = 0;
|
||||
}
|
||||
add(id) {
|
||||
if (!this.sockets.hasOwnProperty(id)) {
|
||||
this.sockets[id] = true;
|
||||
this.length++;
|
||||
}
|
||||
}
|
||||
del(id) {
|
||||
if (this.sockets.hasOwnProperty(id)) {
|
||||
delete this.sockets[id];
|
||||
this.length--;
|
||||
}
|
||||
}
|
||||
}
|
@ -7,9 +7,9 @@ import { SocketIO } from './interfaces'
|
||||
|
||||
const parser = new Parser();
|
||||
|
||||
export class SocketIOClient implements SocketIO.Client {
|
||||
export class Client extends EventEmitter implements SocketIO.Client {
|
||||
private nettyClient: NettyClient;
|
||||
private event: EventEmitter
|
||||
private event: EventEmitter;
|
||||
private _id: string;
|
||||
|
||||
server: SocketIO.Server;
|
||||
@ -18,67 +18,37 @@ export class SocketIOClient implements SocketIO.Client {
|
||||
sockets: { [id: string]: SocketIO.Socket; };
|
||||
nsps: { [nsp: string]: SocketIO.Socket; };
|
||||
|
||||
constructor(nettyClient: NettyClient) {
|
||||
this.event = new EventEmitter()
|
||||
constructor(server: SocketIO.Server, nettyClient: NettyClient) {
|
||||
super();
|
||||
this.server = server;
|
||||
this.event = new EventEmitter();
|
||||
this.conn = nettyClient;
|
||||
this.nettyClient = nettyClient;
|
||||
this._id = this.nettyClient.id;
|
||||
this.event.emit('connect', this);
|
||||
this.nettyClient.on(ServerEvent.message, (text) => this.process(text))
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this._id;
|
||||
}
|
||||
connect() {
|
||||
this.packet({
|
||||
type: PacketTypes.OPEN,
|
||||
data: {
|
||||
sid: this._id,
|
||||
upgrades: [],
|
||||
pingInterval: 25000,
|
||||
pingTimeout: 5000
|
||||
}
|
||||
})
|
||||
this.packet({
|
||||
type: PacketTypes.MESSAGE,
|
||||
sub_type: SubPacketTypes.CONNECT
|
||||
})
|
||||
on(event: string, callback: (...args: any[]) => void) {
|
||||
this.event.on(event, callback);
|
||||
return this
|
||||
}
|
||||
emit(event: string, data: any) {
|
||||
emit(event: string, ...args: any[]): boolean {
|
||||
this.packet({
|
||||
type: PacketTypes.MESSAGE,
|
||||
sub_type: SubPacketTypes.EVENT,
|
||||
name: event,
|
||||
data
|
||||
data: args[0]
|
||||
})
|
||||
return true;
|
||||
}
|
||||
send(data: any) {
|
||||
this.emit("message", data);
|
||||
}
|
||||
process(packet: Packet) {
|
||||
this.event.emit(packet.name, packet.data);
|
||||
}
|
||||
packet(packet: Packet) {
|
||||
this.nettyClient.send(parser.encode(packet))
|
||||
}
|
||||
|
||||
private process(text: string) {
|
||||
let packet = parser.decode(text);
|
||||
switch (packet.type) {
|
||||
case PacketTypes.OPEN:
|
||||
break;
|
||||
case PacketTypes.PING:
|
||||
this.packet({
|
||||
type: PacketTypes.PONG
|
||||
})
|
||||
break;
|
||||
case PacketTypes.MESSAGE:
|
||||
switch (packet.sub_type) {
|
||||
case SubPacketTypes.CONNECT:
|
||||
this.nettyClient.send(text);
|
||||
break;
|
||||
case SubPacketTypes.EVENT:
|
||||
this.event.emit(packet.name, packet.data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,35 +4,37 @@ import { NettyWebSocketServer } from '../server'
|
||||
import { ServerEvent } from '../server/constants';
|
||||
|
||||
import { Namespace } from './namespace';
|
||||
import { SocketIOClient } from './client';
|
||||
import { Client } from './client';
|
||||
import { SocketIO } from './interfaces'
|
||||
import { Parser } from './parser'
|
||||
import { PacketTypes, SubPacketTypes } from './types';
|
||||
import { Packet } from './packet';
|
||||
import { Socket } from './socket';
|
||||
import { Adapter } from './adapter';
|
||||
|
||||
export class SocketIOServer implements SocketIO.Server {
|
||||
class Server implements SocketIO.Server {
|
||||
private event: EventEmitter;
|
||||
private nettyServer: NettyWebSocketServer;
|
||||
private allClients: { [key: string]: SocketIOClient };
|
||||
private namespaces: { [key: string]: Namespace };
|
||||
private allClients: { [key: string]: Client };
|
||||
|
||||
engine: { ws: any; };
|
||||
nsps: { [namespace: string]: SocketIO.Namespace; };
|
||||
sockets: SocketIO.Namespace;
|
||||
nsps: { [namespace: string]: Namespace; };
|
||||
sockets: Namespace;
|
||||
json: SocketIO.Server;
|
||||
volatile: SocketIO.Server;
|
||||
local: SocketIO.Server;
|
||||
parser = new Parser();
|
||||
_adapter: Adapter;
|
||||
options: SocketIO.ServerOptions;
|
||||
|
||||
constructor(pipeline: any, options: SocketIO.ServerOptions) {
|
||||
if (!pipeline) { throw new Error('Netty Pipeline can\'t be undefiend!') }
|
||||
this.event = new EventEmitter();
|
||||
this.allClients = {};
|
||||
this.namespaces = {};
|
||||
this.nettyServer = new NettyWebSocketServer(pipeline, {
|
||||
|
||||
});
|
||||
this.nettyServer.on(ServerEvent.connect, (nettyClient) => {
|
||||
let client = new SocketIOClient(nettyClient);
|
||||
this.allClients[client.id] = client;
|
||||
client.connect();
|
||||
})
|
||||
this.nsps = {};
|
||||
this.sockets = new Namespace('/');
|
||||
this.nsps['/'] = this.sockets;
|
||||
this.initNettyServer(pipeline, options);
|
||||
}
|
||||
|
||||
checkRequest(req: any, fn: (err: any, success: boolean) => void): void {
|
||||
@ -46,12 +48,21 @@ export class SocketIOServer implements SocketIO.Server {
|
||||
path(): string;
|
||||
path(v: string): SocketIO.Server;
|
||||
path(v?: any): string | SocketIO.Server {
|
||||
if (!arguments.length) return this.options.path;
|
||||
this.options.path = v.replace(/\/$/, '');
|
||||
return this;
|
||||
}
|
||||
adapter();
|
||||
adapter(): Adapter;
|
||||
adapter(v: any): SocketIO.Server;
|
||||
adapter(v?: any): SocketIO.Server {
|
||||
throw new Error("Method not implemented.");
|
||||
adapter(v?: any): Adapter | SocketIO.Server {
|
||||
if (!arguments.length) return this._adapter;
|
||||
this._adapter = v;
|
||||
for (var i in this.nsps) {
|
||||
if (this.nsps.hasOwnProperty(i)) {
|
||||
this.nsps[i].initAdapter();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
origins(): string | string[];
|
||||
origins(v: string | string[]): SocketIO.Server;
|
||||
@ -73,10 +84,23 @@ export class SocketIOServer implements SocketIO.Server {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
onconnection(socket: any): SocketIO.Server {
|
||||
throw new Error("Method not implemented.");
|
||||
socket.packet({
|
||||
type: PacketTypes.OPEN,
|
||||
data: {
|
||||
sid: socket.id,
|
||||
upgrades: [],
|
||||
pingInterval: 25000,
|
||||
pingTimeout: 5000
|
||||
}
|
||||
})
|
||||
this.sockets.add(socket);
|
||||
return this;
|
||||
}
|
||||
of(nsp: string | Function | RegExp): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
of(nsp: string): SocketIO.Namespace {
|
||||
if (!this.nsps[nsp]) {
|
||||
this.nsps[nsp] = new Namespace(nsp);
|
||||
}
|
||||
return this.nsps[nsp];
|
||||
}
|
||||
close(fn?: () => void): void {
|
||||
throw new Error("Method not implemented.");
|
||||
@ -85,7 +109,8 @@ export class SocketIOServer implements SocketIO.Server {
|
||||
on(event: "connect", listener: (socket: SocketIO.Socket) => void): SocketIO.Namespace;
|
||||
on(event: string, listener: Function): SocketIO.Namespace;
|
||||
on(event: any, listener: any): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
this.event.on(event, listener);
|
||||
return this.sockets;
|
||||
}
|
||||
to(room: string): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
@ -97,22 +122,72 @@ export class SocketIOServer implements SocketIO.Server {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
emit(event: string, ...args: any[]): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
this.sockets.emit(event, ...args);
|
||||
return this.sockets;
|
||||
}
|
||||
send(...args: any[]): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
this.sockets.send(...args);
|
||||
return this.sockets;
|
||||
}
|
||||
write(...args: any[]): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
this.sockets.write(...args);
|
||||
return this.sockets;
|
||||
}
|
||||
clients(...args: any[]): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
this.sockets.clients(args[0]);
|
||||
return this.sockets;
|
||||
}
|
||||
compress(...args: any[]): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.nettyServer.disable();
|
||||
}
|
||||
|
||||
private initNettyServer(pipeline, options) {
|
||||
this.nettyServer = new NettyWebSocketServer(pipeline, {
|
||||
event: new EventEmitter(),
|
||||
path: options.path
|
||||
});
|
||||
this.nettyServer.on(ServerEvent.connect, (nettyClient) => {
|
||||
let client = new Client(this, nettyClient);
|
||||
this.onconnection(client);
|
||||
})
|
||||
this.nettyServer.on(ServerEvent.message, (nettyClient, text) => {
|
||||
this.processPacket(this.parser.decode(text), this.allClients[nettyClient.id]);
|
||||
})
|
||||
}
|
||||
|
||||
private processPacket(packet: Packet, client: Client) {
|
||||
switch (packet.type) {
|
||||
case PacketTypes.PING:
|
||||
client.packet({
|
||||
type: PacketTypes.PONG,
|
||||
data: packet.data
|
||||
})
|
||||
break;
|
||||
case PacketTypes.UPGRADE:
|
||||
break;
|
||||
case PacketTypes.MESSAGE:
|
||||
this.processSubPacket(packet, client);
|
||||
break;
|
||||
case PacketTypes.CLOSE:
|
||||
}
|
||||
}
|
||||
|
||||
private processSubPacket(packet: Packet, client: Client) {
|
||||
switch (packet.sub_type) {
|
||||
case SubPacketTypes.CONNECT:
|
||||
client.packet(packet);
|
||||
break;
|
||||
case SubPacketTypes.EVENT:
|
||||
client.process(packet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
Server,
|
||||
Server as SocketIOServer,
|
||||
Client as SocketIOClient
|
||||
}
|
@ -1,96 +1,66 @@
|
||||
import { EventEmitter } from 'events'
|
||||
|
||||
import { SocketIOClient } from './client'
|
||||
import { Client } from './client'
|
||||
import { SocketIO } from './interfaces';
|
||||
import { ServerEvent } from '../server';
|
||||
import { Socket } from './socket';
|
||||
import { Adapter } from './adapter';
|
||||
import { Server } from './index'
|
||||
|
||||
export class Namespace implements SocketIO.Namespace {
|
||||
private event: EventEmitter;
|
||||
private allClients: { [key: string]: SocketIOClient };
|
||||
private roomClients: { [key: string]: Set<string> };
|
||||
private clientRooms: { [key: string]: Set<string> };
|
||||
|
||||
export class Namespace extends EventEmitter implements SocketIO.Namespace {
|
||||
name: string;
|
||||
server: SocketIO.Server;
|
||||
server: Server;
|
||||
sockets: { [id: string]: SocketIO.Socket; };
|
||||
connected: { [id: string]: SocketIO.Socket; };
|
||||
adapter: SocketIO.Adapter;
|
||||
json: SocketIO.Namespace;
|
||||
|
||||
constructor(name: string) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.event = new EventEmitter();
|
||||
this.allClients = {};
|
||||
this.roomClients = {};
|
||||
this.clientRooms = {};
|
||||
this.sockets = {};
|
||||
this.connected = {};
|
||||
this.adapter = new Adapter(this);
|
||||
}
|
||||
initAdapter() {
|
||||
let adp = this.server.adapter()
|
||||
this.adapter = new adp()
|
||||
}
|
||||
add(client: Client) {
|
||||
let nameClient = new Socket(this, client, {});
|
||||
this.sockets[client.id] = nameClient;
|
||||
client.nsps[this.name] = nameClient;
|
||||
this.onconnection(nameClient);
|
||||
}
|
||||
use(fn: (socket: SocketIO.Socket, fn: (err?: any) => void) => void): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
to(room: string): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
in(room: string): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
send(...args: any[]): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
write(...args: any[]): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
on(event: "connection", listener: (socket: SocketIO.Socket) => void): this;
|
||||
on(event: "connect", listener: (socket: SocketIO.Socket) => void): this;
|
||||
on(event: string, listener: Function): this;
|
||||
on(event: any, listener: any) {
|
||||
// TODO
|
||||
return this;
|
||||
}
|
||||
to(room: string): SocketIO.Namespace {
|
||||
// TODO
|
||||
return this;
|
||||
}
|
||||
in(room: string): SocketIO.Namespace {
|
||||
return this.to(room);
|
||||
}
|
||||
send(...args: any[]): SocketIO.Namespace {
|
||||
// TODO
|
||||
return this;
|
||||
}
|
||||
write(...args: any[]): SocketIO.Namespace {
|
||||
return this.send(...args);
|
||||
}
|
||||
clients(fn: Function): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
return fn(Object.values(this.sockets))
|
||||
}
|
||||
compress(compress: boolean): SocketIO.Namespace {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
addListener(event: string | symbol, listener: (...args: any[]) => void): this {
|
||||
throw new Error("Method not implemented.");
|
||||
private onconnection(socket: any) {
|
||||
let client = socket as Socket;
|
||||
this.sockets[client.id] = client;
|
||||
client.onconnect()
|
||||
this.emit(ServerEvent.connect, socket);
|
||||
this.emit(ServerEvent.connection, socket);
|
||||
}
|
||||
once(event: string | symbol, listener: (...args: any[]) => void): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
removeListener(event: string | symbol, listener: (...args: any[]) => void): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
off(event: string | symbol, listener: (...args: any[]) => void): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
removeAllListeners(event?: string | symbol): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
setMaxListeners(n: number): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
getMaxListeners(): number {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
listeners(event: string | symbol): Function[] {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
rawListeners(event: string | symbol): Function[] {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
emit(event: string | symbol, ...args: any[]): boolean {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
listenerCount(type: string | symbol): number {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
prependListener(event: string | symbol, listener: (...args: any[]) => void): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
eventNames(): (string | symbol)[] {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
|
110
packages/websocket/src/socket-io/socket.ts
Normal file
110
packages/websocket/src/socket-io/socket.ts
Normal file
@ -0,0 +1,110 @@
|
||||
import { EventEmitter } from 'events'
|
||||
|
||||
import { SocketIOClient } from "socket-io";
|
||||
import { SocketIO } from "./interfaces";
|
||||
import { Packet } from './packet';
|
||||
import { PacketTypes, SubPacketTypes } from './types';
|
||||
|
||||
export class Socket extends EventEmitter implements SocketIO.Socket {
|
||||
nsp: SocketIO.Namespace;
|
||||
server: SocketIO.Server;
|
||||
adapter: SocketIO.Adapter;
|
||||
id: string;
|
||||
request: any;
|
||||
client: SocketIOClient;
|
||||
conn: SocketIO.EngineSocket;
|
||||
rooms: { [id: string]: string; };
|
||||
connected: boolean;
|
||||
disconnected: boolean;
|
||||
handshake: SocketIO.Handshake;
|
||||
json: SocketIO.Socket;
|
||||
volatile: SocketIO.Socket;
|
||||
broadcast: SocketIO.Socket;
|
||||
fns: any[];
|
||||
_rooms: string[];
|
||||
|
||||
constructor(nsp, client, query) {
|
||||
super();
|
||||
this.nsp = nsp;
|
||||
this.server = nsp.server;
|
||||
this.adapter = this.nsp.adapter;
|
||||
this.id = nsp.name !== '/' ? nsp.name + '#' + client.id : client.id;
|
||||
this.client = client;
|
||||
this.conn = client.conn;
|
||||
this.rooms = {};
|
||||
// this.acks = {};
|
||||
this.connected = true;
|
||||
this.disconnected = false;
|
||||
// this.handshake = this.buildHandshake(query);
|
||||
this.fns = [];
|
||||
// this.flags = {};
|
||||
this._rooms = [];
|
||||
}
|
||||
|
||||
to(room: string): SocketIO.Socket {
|
||||
if (!~this._rooms.indexOf(room)) this._rooms.push(room);
|
||||
return this;
|
||||
}
|
||||
in(room: string): SocketIO.Socket {
|
||||
return this.to(room);
|
||||
}
|
||||
use(fn: (packet: SocketIO.Packet, next: (err?: any) => void) => void): SocketIO.Socket {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
send(...args: any[]): SocketIO.Socket {
|
||||
this.emit("message", ...args)
|
||||
return this;
|
||||
}
|
||||
write(...args: any[]): SocketIO.Socket {
|
||||
return this.send(...args);
|
||||
}
|
||||
join(rooms: string | string[], fn?: (err?: any) => void): SocketIO.Socket {
|
||||
if (!Array.isArray(rooms)) {
|
||||
rooms = [rooms];
|
||||
}
|
||||
rooms = rooms.filter((room) => {
|
||||
return !this.rooms.hasOwnProperty(room);
|
||||
});
|
||||
if (!rooms.length) {
|
||||
fn && fn(null);
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
leave(name: string, fn?: Function): SocketIO.Socket {
|
||||
delete this.rooms[name];
|
||||
fn && fn(null)
|
||||
return this;
|
||||
}
|
||||
leaveAll(): void {
|
||||
this.adapter.delAll(this.id);
|
||||
this.rooms = {};
|
||||
}
|
||||
disconnect(close?: boolean): SocketIO.Socket {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
compress(compress: boolean): SocketIO.Socket {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
error(err: any): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
packet(packet: Packet) {
|
||||
this.client.packet(packet);
|
||||
}
|
||||
|
||||
onconnect() {
|
||||
this.nsp.connected[this.id] = this;
|
||||
this.join(this.id);
|
||||
// var skip = this.nsp.name === '/' && this.nsp.fns.length === 0;
|
||||
// if (skip) {
|
||||
// debug('packet already sent in initial handshake');
|
||||
// } else {
|
||||
this.packet({
|
||||
type: PacketTypes.MESSAGE,
|
||||
sub_type: SubPacketTypes.CONNECT
|
||||
});
|
||||
// }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user