feat: export error handle & merge config

Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
MiaoWoo 2020-03-24 18:30:50 +08:00
parent 100ccbcde3
commit c505cda10b
7 changed files with 44 additions and 41 deletions

View File

@ -1,6 +0,0 @@
import { EventEmitter } from 'events'
export interface NettyWebSocketServerOptions {
event: EventEmitter,
path?: string;
}

View File

@ -3,6 +3,7 @@ export enum ServerEvent {
connect = 'connect', connect = 'connect',
connection = 'connection', connection = 'connection',
message = 'message', message = 'message',
error = 'error',
disconnect = 'disconnect' disconnect = 'disconnect'
} }

View File

@ -1,5 +1,6 @@
import { HttpRequestHandlerAdapter } from '../netty' import { HttpRequestHandlerAdapter } from '../netty'
import { Keys, AttributeKeys } from './constants' import { AttributeKeys } from './constants'
import { ServerOptions } from 'socket-io'
const DefaultHttpResponse = Java.type('io.netty.handler.codec.http.DefaultHttpResponse') const DefaultHttpResponse = Java.type('io.netty.handler.codec.http.DefaultHttpResponse')
const DefaultFullHttpResponse = Java.type('io.netty.handler.codec.http.DefaultFullHttpResponse') const DefaultFullHttpResponse = Java.type('io.netty.handler.codec.http.DefaultFullHttpResponse')
@ -14,21 +15,13 @@ const RandomAccessFile = Java.type('java.io.RandomAccessFile')
const DefaultFileRegion = Java.type('io.netty.channel.DefaultFileRegion') const DefaultFileRegion = Java.type('io.netty.channel.DefaultFileRegion')
const ChannelFutureListener = Java.type('io.netty.channel.ChannelFutureListener') const ChannelFutureListener = Java.type('io.netty.channel.ChannelFutureListener')
export type HttpRequestConfig = {
root?: string;
ws?: string;
}
export class HttpRequestHandler extends HttpRequestHandlerAdapter { export class HttpRequestHandler extends HttpRequestHandlerAdapter {
private ws: string; private ws: string;
private root: string; private root: string;
constructor(config: HttpRequestConfig = { constructor(options: ServerOptions) {
root: root + '/wwwroot',
ws: '/ws'
}) {
super() super()
this.root = config.root; this.root = options.root;
this.ws = config.ws; this.ws = options.path;
} }
channelRead0(ctx: any, request: any) { channelRead0(ctx: any, request: any) {
if (request.getUri().startsWith(this.ws)) { if (request.getUri().startsWith(this.ws)) {

View File

@ -4,17 +4,18 @@ import { ServerEvent, Keys } from './constants'
import { WebSocketDetect } from './websocket_detect' import { WebSocketDetect } from './websocket_detect'
import { WebSocketHandler } from './websocket_handler' import { WebSocketHandler } from './websocket_handler'
import { NettyClient } from './client' import { NettyClient } from './client'
import { NettyWebSocketServerOptions } from './config' import { ServerOptions, Server } from '../socket-io'
class NettyWebSocketServer extends EventEmitter { class NettyWebSocketServer extends 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: ServerOptions) {
super() super()
this.allClients = {}; this.allClients = {};
this.pipeline = pipeline; this.pipeline = pipeline;
let connectEvent = options.event; let connectEvent = options.event;
try { this.pipeline.remove(Keys.Detect) } catch (error) { }
this.pipeline.addFirst(Keys.Detect, new WebSocketDetect(connectEvent).getHandler()) this.pipeline.addFirst(Keys.Detect, new WebSocketDetect(connectEvent).getHandler())
connectEvent.on(ServerEvent.detect, (ctx, channel) => { connectEvent.on(ServerEvent.detect, (ctx, channel) => {
channel.pipeline().addFirst(Keys.Handler, new WebSocketHandler(options).getHandler()) channel.pipeline().addFirst(Keys.Handler, new WebSocketHandler(options).getHandler())
@ -26,8 +27,10 @@ class NettyWebSocketServer extends EventEmitter {
this.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(); this.emit(ServerEvent.message, this.allClients[ctx.channel().id()], msg.text())
this.emit(ServerEvent.message, this.allClients[channel.id()], msg.text()) })
connectEvent.on(ServerEvent.error, (ctx, cause) => {
this.emit(ServerEvent.error, this.allClients[ctx.channel().id()], cause)
}) })
} }
close() { close() {

View File

@ -1,11 +1,11 @@
import { TextWebSocketFrameHandlerAdapter } from '../netty' import { TextWebSocketFrameHandlerAdapter } from '../netty'
import { EventEmitter } from 'events' import { EventEmitter } from 'events'
import { ServerEvent } from './constants' import { ServerEvent } from './constants'
import { NettyWebSocketServerOptions } from './config'; import { ServerOptions } from '../socket-io';
export class TextWebSocketFrameHandler extends TextWebSocketFrameHandlerAdapter { export class TextWebSocketFrameHandler extends TextWebSocketFrameHandlerAdapter {
private event: EventEmitter; private event: EventEmitter;
constructor(options: NettyWebSocketServerOptions) { constructor(options: ServerOptions) {
super() super()
this.event = options.event; this.event = options.event;
} }
@ -18,6 +18,6 @@ export class TextWebSocketFrameHandler extends TextWebSocketFrameHandlerAdapter
this.event.emit(ServerEvent.message, ctx, msg) this.event.emit(ServerEvent.message, ctx, msg)
} }
exceptionCaught(ctx: any, cause: Error) { exceptionCaught(ctx: any, cause: Error) {
console.ex(cause) this.event.emit(ServerEvent.error, ctx, cause)
} }
} }

View File

@ -4,7 +4,7 @@ import { Keys } from './constants'
import { WebSocketHandlerAdapter } from "../netty" import { WebSocketHandlerAdapter } from "../netty"
import { HttpRequestHandler } from './httprequest' import { HttpRequestHandler } from './httprequest'
import { TextWebSocketFrameHandler } from './text_websocket_frame' import { TextWebSocketFrameHandler } from './text_websocket_frame'
import { NettyWebSocketServerOptions } from './config' import { ServerOptions } from '../socket-io'
const CharsetUtil = Java.type('io.netty.util.CharsetUtil') const CharsetUtil = Java.type('io.netty.util.CharsetUtil')
@ -14,8 +14,8 @@ const HttpObjectAggregator = Java.type('io.netty.handler.codec.http.HttpObjectAg
const WebSocketServerProtocolHandler = Java.type('io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler') const WebSocketServerProtocolHandler = Java.type('io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler')
export class WebSocketHandler extends WebSocketHandlerAdapter { export class WebSocketHandler extends WebSocketHandlerAdapter {
private options: NettyWebSocketServerOptions; private options: ServerOptions;
constructor(options: NettyWebSocketServerOptions) { constructor(options: ServerOptions) {
super() super()
this.options = options; this.options = options;
} }
@ -32,7 +32,7 @@ export class WebSocketHandler extends WebSocketHandlerAdapter {
pipeline.addLast('http', new HttpServerCodec()) pipeline.addLast('http', new HttpServerCodec())
pipeline.addLast('chunk', new ChunkedWriteHandler()) pipeline.addLast('chunk', new ChunkedWriteHandler())
pipeline.addLast('httpobj', new HttpObjectAggregator(64 * 1024)) pipeline.addLast('httpobj', new HttpObjectAggregator(64 * 1024))
pipeline.addLast('http_request', new HttpRequestHandler().getHandler()) pipeline.addLast('http_request', new HttpRequestHandler(this.options).getHandler())
pipeline.addLast('websocket', new WebSocketServerProtocolHandler(this.options.path, true)) pipeline.addLast('websocket', new WebSocketServerProtocolHandler(this.options.path, true))
pipeline.addLast('websocket_handler', new TextWebSocketFrameHandler(this.options).getHandler()) pipeline.addLast('websocket_handler', new TextWebSocketFrameHandler(this.options).getHandler())
} }

View File

@ -1,6 +1,6 @@
import { EventEmitter } from 'events' import { EventEmitter } from 'events'
import { NettyWebSocketServer } from '../server' import { NettyWebSocketServer, NettyClient } from '../server'
import { ServerEvent } from '../server/constants'; import { ServerEvent } from '../server/constants';
import { Namespace } from './namespace'; import { Namespace } from './namespace';
@ -12,6 +12,17 @@ import { Packet } from './packet';
import { Socket } from './socket'; import { Socket } from './socket';
import { Adapter } from './adapter'; import { Adapter } from './adapter';
interface ServerOptions extends SocketIO.ServerOptions {
event?: EventEmitter;
root?: string;
}
const defaultOptions: ServerOptions = {
event: new EventEmitter(),
path: '/socket.io',
root: root + '/wwwroot'
}
class Server implements SocketIO.Server { class Server implements SocketIO.Server {
private nettyServer: NettyWebSocketServer; private nettyServer: NettyWebSocketServer;
private allClients: { [key: string]: Client }; private allClients: { [key: string]: Client };
@ -24,15 +35,15 @@ class Server implements SocketIO.Server {
local: SocketIO.Server; local: SocketIO.Server;
parser = new Parser(); parser = new Parser();
_adapter: Adapter; _adapter: Adapter;
options: SocketIO.ServerOptions; options: ServerOptions;
constructor(pipeline: any, options: SocketIO.ServerOptions) { constructor(pipeline: any, options: ServerOptions) {
if (!pipeline) { throw new Error('Netty Pipeline can\'t be undefiend!') } if (!pipeline) { throw new Error('Netty Pipeline can\'t be undefiend!') }
this.allClients = {}; this.allClients = {};
this.nsps = {}; this.nsps = {};
this.sockets = new Namespace('/', this); this.sockets = new Namespace('/', this);
this.nsps['/'] = this.sockets; this.nsps['/'] = this.sockets;
this.initNettyServer(pipeline, options); this.initNettyServer(pipeline, Object.assign(defaultOptions, options));
} }
checkRequest(req: any, fn: (err: any, success: boolean) => void): void { checkRequest(req: any, fn: (err: any, success: boolean) => void): void {
@ -144,17 +155,18 @@ class Server implements SocketIO.Server {
}; };
private initNettyServer(pipeline, options) { private initNettyServer(pipeline, options) {
this.nettyServer = new NettyWebSocketServer(pipeline, { this.nettyServer = new NettyWebSocketServer(pipeline, options);
event: new EventEmitter(), this.nettyServer.on(ServerEvent.connect, (nettyClient: NettyClient) => {
path: options.path
});
this.nettyServer.on(ServerEvent.connect, (nettyClient) => {
let client = new Client(this, nettyClient); let client = new Client(this, nettyClient);
this.onconnection(client); this.onconnection(client);
}) })
this.nettyServer.on(ServerEvent.message, (nettyClient, text) => { this.nettyServer.on(ServerEvent.message, (nettyClient: NettyClient, text) => {
this.processPacket(this.parser.decode(text), this.allClients[nettyClient.id]); this.processPacket(this.parser.decode(text), this.allClients[nettyClient.id]);
}) })
this.nettyServer.on(ServerEvent.error, (nettyClient: NettyClient, cause) => {
console.error(`Client ${nettyClient.id} cause error: ` + cause)
console.ex(cause)
})
} }
private processPacket(packet: Packet, client: Client) { private processPacket(packet: Packet, client: Client) {
@ -193,6 +205,6 @@ class Server implements SocketIO.Server {
export { export {
Server, Server,
Socket, Socket,
Server as SocketIOServer, Client,
Client as SocketIOClient ServerOptions
} }