143 lines
4.2 KiB
TypeScript
143 lines
4.2 KiB
TypeScript
import { EventEmitter } from 'events'
|
|
|
|
import { Client } from './client'
|
|
import { SocketIO } from './interfaces'
|
|
import { ServerEvent } from './constants'
|
|
import { Socket } from './socket'
|
|
import { Adapter } from './adapter'
|
|
import { Server } from './index'
|
|
import { Packet } from './packet'
|
|
import { PacketTypes, SubPacketTypes } from './types'
|
|
|
|
export class Namespace extends EventEmitter implements SocketIO.Namespace {
|
|
name: string
|
|
server: Server
|
|
sockets: { [id: string]: Socket }
|
|
connected: { [id: string]: Socket }
|
|
adapter: SocketIO.Adapter
|
|
json: SocketIO.Namespace
|
|
|
|
fns: any[]
|
|
ids: number
|
|
rooms: string[]
|
|
flags: { [key: string]: boolean }
|
|
|
|
private events = ['connect', 'connection', 'newListener']
|
|
|
|
constructor(name: string, server: Server) {
|
|
super()
|
|
this.name = name
|
|
this.server = server
|
|
this.sockets = {}
|
|
this.connected = {}
|
|
this.fns = []
|
|
this.ids = 0
|
|
this.rooms = []
|
|
this.flags = {}
|
|
this.adapter = new Adapter(this)
|
|
}
|
|
initAdapter() {
|
|
// @ts-ignore
|
|
this.adapter = new (this.server.adapter())()
|
|
}
|
|
add(client: Client, query?: any, callback?: () => void) {
|
|
// client.conn.request.url();
|
|
let socket = new Socket(this, client, {})
|
|
this.sockets[client.id] = socket
|
|
client.nsps[this.name] = socket
|
|
this.onconnection(socket)
|
|
return socket
|
|
}
|
|
del(client: Client) {
|
|
let socket = this.sockets[client.id]
|
|
socket.disconnect()
|
|
delete this.sockets[client.id]
|
|
}
|
|
use(fn: (socket: SocketIO.Socket, fn: (err?: any) => void) => void): SocketIO.Namespace {
|
|
throw new Error("Method not implemented.")
|
|
}
|
|
to(room: string): SocketIO.Namespace {
|
|
if (!~this.rooms.indexOf(room)) this.rooms.push(room)
|
|
return this
|
|
}
|
|
in(room: string): SocketIO.Namespace {
|
|
return this.to(room)
|
|
}
|
|
send(...args: any[]): SocketIO.Namespace {
|
|
super.emit('message', ...args)
|
|
return this
|
|
}
|
|
write(...args: any[]): SocketIO.Namespace {
|
|
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: PacketTypes.MESSAGE,
|
|
sub_type: (this.flags.binary !== undefined ? this.flags.binary : this.hasBin(args)) ? SubPacketTypes.BINARY_EVENT : SubPacketTypes.EVENT,
|
|
name: 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: (sockets: Socket[]) => SocketIO.Namespace): SocketIO.Namespace {
|
|
return fn(Object.values(this.sockets))
|
|
}
|
|
compress(compress: boolean): SocketIO.Namespace {
|
|
throw new Error("Method not implemented.")
|
|
}
|
|
process(packet: Packet, client: Client) {
|
|
switch (packet.sub_type) {
|
|
case SubPacketTypes.CONNECT:
|
|
this.add(client)
|
|
break
|
|
default:
|
|
this.sockets[client.id].onpacket(packet)
|
|
break
|
|
}
|
|
}
|
|
remove(socket: Socket) {
|
|
if (this.sockets.hasOwnProperty(socket.id)) {
|
|
delete this.sockets[socket.id]
|
|
} else {
|
|
// debug('ignoring remove for %s', socket.id);
|
|
}
|
|
}
|
|
close() {
|
|
this.removeAllListeners('connect')
|
|
Object.values(this.sockets).forEach(socket => socket.disconnect(false))
|
|
}
|
|
private onconnection(socket: any) {
|
|
let client = socket as Socket
|
|
this.sockets[client.id] = client
|
|
this.emit(ServerEvent.connect, socket)
|
|
client.onconnect()
|
|
this.emit(ServerEvent.connection, socket)
|
|
}
|
|
}
|