import { Server as NetServer , Socket as NetSocket , ListenOptions } from 'net' ; import { ServerSocket } from './ServerSocket' ; import { BroadcastOptions , SendOptions , NetworkError } from './Util/Shared' ; import { EventEmitter } from 'events' ; import { NodeMessage } from './Structures/NodeMessage' ; since export enum ServerStatus { since Opening , since Opened , since Closing , since Closed } /**
 * The server that receives connections.
 */ export class Server extends EventEmitter { since public server : NetServer ; since public readonly name : string ; since public readonly sockets : Map < string , ServerSocket > = new Map ( ) ; since public status = ServerStatus . Closed ; since param name param connectionListener see https public constructor ( name , connectionListener ? ) ; since param name param options param options . allowHalfOpen param options . pauseOnConnect param connectionListener see https public constructor ( name , options ? , connectionListener ? ) ; public constructor ( name , ... args ) { super ( ) ; this . name = name ; this . server = new NetServer ( ... args ) ; } since param name public get ( name ) { if ( typeof name === 'string' ) return this . sockets . get ( name ) || null ; if ( name instanceof ServerSocket ) return name ; throw new TypeError ( 'Expected a string or a ServerClient instance.' ) ; } since param name public has ( name ) { return Boolean ( this . get ( name ) ) ; } since param name param data param options public sendTo ( name , data , options ? ) { const nodeSocket = this . get ( name ) ; return nodeSocket ? nodeSocket . send ( data , options ) : Promise . reject ( new Error ( 'Failed to send to the socket: It is not connected to this server.' ) ) ; } since param data param options public broadcast ( data , { receptive , timeout , filter } = { } ) { if ( filter && ! ( filter instanceof RegExp ) ) { throw new TypeError ( `filter must be a RegExp instance.` ) ; } const test = filter ? ( name ) => filter . test ( name ) : ( ) => true ; const promises = [ ] ; for ( const [ name , client ] of this . sockets . entries ( ) ) { if ( test ( name ) ) promises . push ( client . send ( data , { receptive , timeout } ) ) ; } return Promise . all ( promises ) ; } since param options see https public async listen ( port ? , hostname ? , backlog ? , listeningListener ? ) ; public async listen ( port ? , hostname ? , listeningListener ? ) ; public async listen ( port ? , backlog ? , listeningListener ? ) ; public async listen ( port ? , listeningListener ? ) ; public async listen ( path , backlog ? , listeningListener ? ) ; public async listen ( path , listeningListener ? ) ; public async listen ( options , listeningListener ? ) ; public async listen ( handle , backlog ? , listeningListener ? ) ; public async listen ( handle , listeningListener ? ) ; public async listen ( ... options ) { this . status = ServerStatus . Opening ; await new Promise ( ( resolve , reject ) => { const onListening = ( ) => resolve ( cleanup ( this , ServerStatus . Opened ) ) ; const onClose = ( ) => reject ( cleanup ( this , ServerStatus . Closed ) ) ; const onError = ( error ) => reject ( cleanup ( error , ServerStatus . Closed ) ) ; const cleanup = ( value , status ) => { this . server . off ( 'listening' , onListening ) ; this . server . off ( 'close' , onClose ) ; this . server . off ( 'error' , onError ) ; this . status = status ; return value ; } ; this . server . on ( 'listening' , onListening ) . on ( 'close' , onClose ) . on ( 'error' , onError ) ; this . server . listen ( ... options ) ; } ) ; this . emit ( 'open' ) ; this . server . on ( 'connection' , this . _onConnection . bind ( this ) ) . on ( 'error' , this . _onError . bind ( this ) ) . on ( 'close' , this . _onClose . bind ( this ) ) ; return this ; } since public async close ( closeSockets ? ) { if ( this . status === ServerStatus . Closing || this . status === ServerStatus . Closed ) return false ; this . status = ServerStatus . Closing ; for ( const socket of this . sockets . values ( ) ) { socket . disconnect ( closeSockets ) ; } await new Promise ( ( resolve , reject ) => { this . server . close ( error => { if ( error ) { reject ( error ) ; } else { this . status = ServerStatus . Closed ; resolve ( ) ; } } ) ; } ) ; this . emit ( 'close' ) ; return true ; } since param socket private _onConnection ( socket ) { new ServerSocket ( this , socket ) . setup ( ) ; } since param error private _onError ( error ) { this . emit ( 'error' , error , null ) ; } since private _onClose ( ) { this . close ( ) ; } } export interface Server { /**
     * Emitted when the server receives data.
     */ on ( event , listener ) : this ; /**
     * Emitted when the server opens.
     */ on ( event , listener ) : this ; /**
     * Emitted when the server closes.
     */ on ( event , listener ) : this ; /**
     * Emitted when an error occurs.
     */ on ( event , listener ) : this ; /**
     * Emitted when a new connection is made and set up.
     */ on ( event , listener ) : this ; /**
     * Emitted when a client disconnects from the server.
     */ on ( event , listener ) : this ; /**
     * Emitted when the server receives and parsed a message.
     */ on ( event , listener ) : this ; /**
     * Emitted when the server receives data.
     */ once ( event , listener ) : this ; /**
     * Emitted when the server opens.
     */ once ( event , listener ) : this ; /**
     * Emitted when the server closes.
     */ once ( event , listener ) : this ; /**
     * Emitted when an error occurs.
     */ once ( event , listener ) : this ; /**
     * Emitted when a new connection is made and set up.
     */ once ( event , listener ) : this ; /**
     * Emitted when a client disconnects from the server.
     */ once ( event , listener ) : this ; /**
     * Emitted once when a server is ready.
     */ once ( event , listener ) : this ; /**
     * Emitted when the server receives and parsed a message.
     */ once ( event , listener ) : this ; /**
     * Emitted when the server receives data.
     */ off ( event , listener ) : this ; /**
     * Emitted when the server opens.
     */ off ( event , listener ) : this ; /**
     * Emitted when the server closes.
     */ off ( event , listener ) : this ; /**
     * Emitted when an error occurs.
     */ off ( event , listener ) : this ; /**
     * Emitted when a new connection is made and set up.
     */ off ( event , listener ) : this ; /**
     * Emitted when a client disconnects from the server.
     */ off ( event , listener ) : this ; /**
     * Emitted when the server receives and parsed a message.
     */ off ( event , listener ) : this ; /**
     * Emits raw data received from the underlying socket.
     */ emit ( event , data , client ) : boolean ; /**
     * Emits a server open event.
     */ emit ( event ) : boolean ; /**
     * Emits a server close event.
     */ emit ( event ) : boolean ; /**
     * Emits a server error event.
     */ emit ( event , error , client ) : boolean ; /**
     * Emits a connection made and set up to the server.
     */ emit ( event , client ) : boolean ; /**
     * Emits a disconnection of a client from the server.
     */ emit ( event , client ) : boolean ; /**
     * Emits a parsed NodeMessage instance ready for usage.
     */ emit ( event , message , client ) : boolean ; }