@@ -1,52 +1,90 @@
|
||||
import { EventEmitter } from 'events'
|
||||
import { ServerOptions } from '../socket.io'
|
||||
import { WebSocketClient } from './client'
|
||||
|
||||
import { Transport } from '../transport'
|
||||
import type { Request } from './request'
|
||||
|
||||
interface ServerOptions {
|
||||
export enum ServerEvent {
|
||||
detect = 'detect',
|
||||
request = 'request',
|
||||
upgrade = 'upgrade',
|
||||
connect = 'connect',
|
||||
connection = 'connection',
|
||||
message = 'message',
|
||||
error = 'error',
|
||||
disconnecting = 'disconnecting',
|
||||
disconnect = 'disconnect',
|
||||
}
|
||||
|
||||
export interface JavaServerOptions extends ServerOptions {
|
||||
event?: EventEmitter
|
||||
root?: string
|
||||
/**
|
||||
* name of the path to capture
|
||||
* @default "/socket.io"
|
||||
*/
|
||||
path: string
|
||||
}
|
||||
|
||||
interface WebSocketServerImpl extends EventEmitter {
|
||||
close(): void
|
||||
}
|
||||
|
||||
export class WebSocketServer extends EventEmitter {
|
||||
options: Partial<ServerOptions>
|
||||
private websocketServer: WebSocketServerImpl
|
||||
|
||||
constructor(instance: any, options: Partial<ServerOptions>) {
|
||||
export abstract class WebSocketServer extends EventEmitter {
|
||||
protected instance: any
|
||||
protected options: JavaServerOptions
|
||||
private clients: Map<string, WebSocketClient>
|
||||
constructor(instance: any, options: JavaServerOptions) {
|
||||
super()
|
||||
if (!instance) { throw new Error('instance can\'t be undefiend!') }
|
||||
this.options = Object.assign({
|
||||
event: new EventEmitter(),
|
||||
path: '/ws',
|
||||
root: root + '/wwwroot',
|
||||
}, options)
|
||||
this.selectServerImpl(instance)
|
||||
this.instance = instance
|
||||
this.options = options
|
||||
this.clients = new Map()
|
||||
console.debug('create websocket server from ' + this.constructor.name)
|
||||
this.initialize()
|
||||
}
|
||||
|
||||
on(event: "connect", cb: (transport: Transport) => void): this
|
||||
on(event: "message", cb: (transport: Transport, text: string) => void): this
|
||||
on(event: "disconnect", cb: (transport: Transport, reason: string) => void): this
|
||||
on(event: "error", cb: (transport: Transport, cause: Error) => void): this
|
||||
on(event: string, cb: (transport: Transport, extra?: any) => void): this {
|
||||
this.websocketServer.on(event, cb)
|
||||
return this
|
||||
protected onconnect(handler: any) {
|
||||
let id = this.getId(handler)
|
||||
console.log('client', id, 'connect')
|
||||
let request = this.getRequest(handler)
|
||||
request.id = id
|
||||
let websocket = this.getSocket(handler)
|
||||
this.clients.set(this.getId(handler), websocket)
|
||||
this.emit(ServerEvent.connect, request, websocket)
|
||||
}
|
||||
|
||||
private selectServerImpl(instance: any) {
|
||||
let WebSocketServerImpl = undefined
|
||||
if (instance.class.name.startsWith('io.netty.channel')) {
|
||||
WebSocketServerImpl = require("../netty").NettyWebSocketServer
|
||||
} else {
|
||||
WebSocketServerImpl = require("../tomcat").TomcatWebSocketServer
|
||||
protected onmessage(handler: any, message: string) {
|
||||
this.execute(handler, (websocket) => websocket.emit(ServerEvent.message, message))
|
||||
}
|
||||
protected ondisconnect(handler: any, cause: string) {
|
||||
this.execute(handler, (websocket) => websocket.emit(ServerEvent.disconnect, cause))
|
||||
}
|
||||
protected onerror(handler: any, error: Error) {
|
||||
if (global.debug) {
|
||||
console.ex(error)
|
||||
}
|
||||
this.websocketServer = new WebSocketServerImpl(instance, this.options)
|
||||
this.execute(handler, (websocket) => websocket.emit(ServerEvent.error, error))
|
||||
}
|
||||
protected execute(handler: any, callback: (websocket: WebSocketClient) => void) {
|
||||
let id = this.getId(handler)
|
||||
if (this.clients.has(id)) {
|
||||
this.clients.has(id) && callback(this.clients.get(id))
|
||||
} else {
|
||||
console.debug('ignore execute', handler, 'callback', callback)
|
||||
}
|
||||
}
|
||||
public close() {
|
||||
this.clients.forEach(websocket => websocket.close())
|
||||
this.doClose()
|
||||
}
|
||||
protected abstract initialize(): void
|
||||
protected abstract getId(handler: any): string
|
||||
protected abstract getRequest(handler: any): Request
|
||||
protected abstract getSocket(handler: any): WebSocketClient
|
||||
protected abstract doClose(): void
|
||||
}
|
||||
|
||||
export const attach = (instance, options) => {
|
||||
if (!instance) { throw new Error('instance can\'t be undefiend!') }
|
||||
options = Object.assign({
|
||||
event: new EventEmitter(),
|
||||
path: '/ws',
|
||||
root: root + '/wwwroot',
|
||||
}, options)
|
||||
let WebSocketServerImpl = undefined
|
||||
if (instance.class.name.startsWith('io.netty.channel')) {
|
||||
WebSocketServerImpl = require("../netty").NettyWebSocketServer
|
||||
} else {
|
||||
WebSocketServerImpl = require("../tomcat").TomcatWebSocketServer
|
||||
}
|
||||
return new WebSocketServerImpl(instance, options)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user