From 524c06741facb56c089e0d6308f76fa3d6f02799 Mon Sep 17 00:00:00 2001 From: Paul Loyd Date: Sun, 1 Dec 2013 22:55:13 +0400 Subject: [PATCH 1/2] Add websocket --- README.md | 1 + websocket/websocket-tests.ts | 86 +++++++ websocket/websocket.d.ts | 460 +++++++++++++++++++++++++++++++++++ 3 files changed, 547 insertions(+) create mode 100644 websocket/websocket-tests.ts create mode 100644 websocket/websocket.d.ts diff --git a/README.md b/README.md index add083e34..a7ac5f960 100755 --- a/README.md +++ b/README.md @@ -235,6 +235,7 @@ List of Definitions * [Viewporter](https://github.com/zynga/viewporter) (by [Boris Yankov](https://github.com/borisyankov)) * [Vimeo](http://developer.vimeo.com/player/js-api) (by [Daz Wilkin](https://github.com/DazWilkin/)) * [WebRTC](http://dev.w3.org/2011/webrtc/editor/webrtc.html) (by [Ken Smith](https://github.com/smithkl42)) +* [websocket](https://github.com/Worlize/WebSocket-Node) (by [Paul Loyd](https://github.com/loyd)) * [WinJS](http://msdn.microsoft.com/en-us/library/windows/apps/br229773.aspx) (from TypeScript samples) * [WinRT](http://msdn.microsoft.com/en-us/library/windows/apps/br211377.aspx) (from TypeScript samples) * [YouTube](https://developers.google.com/youtube/) (by [Daz Wilkin](https://github.com/DazWilkin/)) diff --git a/websocket/websocket-tests.ts b/websocket/websocket-tests.ts new file mode 100644 index 000000000..e91e8467d --- /dev/null +++ b/websocket/websocket-tests.ts @@ -0,0 +1,86 @@ +/// + +import websocket = require('websocket'); +import http = require('http'); + +{ + var server = http.createServer((req, res) => { + console.log((new Date()) + ' Received request for ' + req.url); + res.writeHead(404); + res.end(); + }); + + server.listen(8080, () => { + console.log((new Date()) + ' Server is listening on port 8080'); + }); + + var wsServer = new websocket.server({ + httpServer: server, + autoAcceptConnections: false + }); + + function originIsAllowed(origin) { return true; } + + wsServer.on('request', (request: websocket.request) => { + if (!originIsAllowed(request.origin)) { + request.reject(); + console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.'); + return; + } + + var connection = request.accept('echo-protocol', request.origin); + console.log((new Date()) + ' Connection accepted.'); + connection.on('message', (message) => { + if (message.type === 'utf8') { + console.log('Received Message: ' + message.utf8Data); + connection.sendUTF(message.utf8Data); + } + else if (message.type === 'binary') { + console.log('Received Binary Message of ' + message.binaryData.length + ' bytes'); + connection.sendBytes(message.binaryData); + } + }); + + connection.on('close', (reasonCode, description) => { + console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.'); + }); + }); +} + +{ + var WebSocketClient = require('websocket').client; + var client = new WebSocketClient(); + + client.on('connectFailed', (error: Error) => { + console.log('Connect Error: ' + error.toString()); + }); + + client.on('connect', (connection: websocket.connection) => { + console.log('WebSocket client connected'); + connection.on('error', (error) => { + console.log("Connection Error: " + error.toString()); + }); + + connection.on('close', () => { + console.log('echo-protocol Connection Closed'); + }); + + connection.on('message', (message) => { + if (message.type === 'utf8') { + console.log("Received: '" + message.utf8Data + "'"); + } + }); + + function sendNumber() { + if (connection.connected) { + var number = Math.round(Math.random() * 0xFFFFFF); + connection.sendUTF(number.toString()); + setTimeout(sendNumber, 1000); + } + } + + sendNumber(); + }); + + client.connect('ws://localhost:8080/', 'echo-protocol'); +} diff --git a/websocket/websocket.d.ts b/websocket/websocket.d.ts new file mode 100644 index 000000000..5f378feb8 --- /dev/null +++ b/websocket/websocket.d.ts @@ -0,0 +1,460 @@ +// Type definitions for websocket +// Project: https://github.com/Worlize/WebSocket-Node +// Definitions by: Paul Loyd +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module "websocket" { + import events = require('events'); + import http = require('http'); + import net = require('net'); + import url = require('url'); + + export interface ServerConfig { + /** The http server instance to attach to */ + httpServer: http.Server; + + /** + * The maximum allowed received frame size in bytes. + * Single frame messages will also be limited to this maximum. + * @default 64KiB + */ + maxReceivedFrameSize?: number; + + /** + * The maximum allowed aggregate message size (for fragmented messages) in bytes. + * @default 1MiB + */ + maxReceivedMessageSize?: number; + + /** + * Whether or not to fragment outgoing messages. If true, messages will be + * automatically fragmented into chunks of up to `fragmentationThreshold` bytes. + * @default true + */ + fragmentOutgoingMessages?: boolean; + + /** + * The maximum size of a frame in bytes before it is automatically fragmented. + * @default 16KiB + */ + fragmentationThreshold?: number; + + /** + * If true, the server will automatically send a ping to all clients every + * `keepaliveInterval` milliseconds. Each client has an independent `keepalive` + * timer, which is reset when any data is received from that client. + * @default true + */ + keepalive?: boolean; + + /** + * The interval in milliseconds to send `keepalive` pings to connected clients. + * @default 20000 + */ + keepaliveInterval?: number; + + /** + * If true, the server will consider any connection that has not received any + * data within the amount of time specified by `keepaliveGracePeriod` after a + * `keepalive` ping has been sent. Ignored if `keepalive` is false. + * @default true + */ + dropConnectionOnKeepaliveTimeout?: boolean; + + /** + * The amount of time to wait after sending a `keepalive` ping before closing + * the connection if the connected peer does not respond. Ignored if `keepalive` + * or `dropConnectionOnKeepaliveTimeout` are false. The grace period timer is + * reset when any data is received from the client. + * @default 10000 + */ + keepaliveGracePeriod?: number; + + /** + * If true, fragmented messages will be automatically assembled and the full + * message will be emitted via a `message` event. If false, each frame will be + * emitted on the `connection` object via a `frame` event and the application + * will be responsible for aggregating multiple fragmented frames. Single-frame + * messages will emit a `message` event in addition to the `frame` event. + * @default true + */ + assembleFragments?: boolean; + + /** + * If this is true, websocket connections will be accepted regardless of the path + * and protocol specified by the client. The protocol accepted will be the first + * that was requested by the client. + * @default false + */ + autoAcceptConnections?: boolean; + + /** + * The number of milliseconds to wait after sending a close frame for an + * `acknowledgement` to come back before giving up and just closing the socket. + * @default 5000 + */ + closeTimeout?: number; + + /** + * The Nagle Algorithm makes more efficient use of network resources by introducing a + * small delay before sending small packets so that multiple messages can be batched + * together before going onto the wire. This however comes at the cost of latency. + * @default true + */ + disableNagleAlgorithm?: boolean; + } + + export class server extends events.EventEmitter { + constructor(serverConfig?: ServerConfig); + + /** Attach the `server` instance to a Node http.Server instance */ + mount(serverConfig: ServerConfig); + + /** + * Detach the `server` instance from the Node http.Server instance. + * All existing connections are left alone and will not be affected, + * but no new WebSocket connections will be accepted. + */ + unmount(); + + /** Close all open WebSocket connections */ + closeAllConnections(); + /** Close all open WebSocket connections and unmount the server */ + shutDown(); + + // Events + on(event: string, listener: Function): server; + on(event: 'request', cb: (request: request) => void): server; + on(event: 'connect', cb: (connection: connection) => void): server; + on(event: 'close', cb: (connection: connection, reason: number, desc: string) => void): server; + addListener(event: string, listener: Function): server; + addListener(event: 'request', cb: (request: request) => void): server; + addListener(event: 'connect', cb: (connection: connection) => void): server; + addListener(event: 'close', cb: (connection: connection, reason: number, desc: string) => void): server; + } + + export class request extends events.EventEmitter { + /** A reference to the original Node HTTP request object */ + httpRequest: http.ClientRequest; + /** This will include the port number if a non-standard port is used */ + host: string; + /** A string containing the path that was requested by the client */ + resource: string; + /** Parsed resource, including the query string parameters */ + resourceURL: url.Url; + + /** + * Client's IP. If an `X-Forwarded-For` header is present, the value will be taken + * from that header to facilitate WebSocket servers that live behind a reverse-proxy + */ + remoteAddress: string; + + /** + * If the client is a web browser, origin will be a string containing the URL + * of the page containing the script that opened the connection. + * If the client is not a web browser, origin may be `null` or "*". + */ + origin: string; + + /** The version of the WebSocket protocol requested by the client */ + webSocketVersion: number; + /** An array containing a list of extensions requested by the client */ + requestedExtensions: any[]; + + /** + * List of strings that indicate the subprotocols the client would like to speak. + * The server should select the best one that it can support from the list and + * pass it to the `accept` function when accepting the connection. + * Note that all the strings in the `requestedProtocols` array will have been + * converted to lower case. + */ + requestedProtocols: string[]; + + constructor(socket: net.NodeSocket, httpRequest: http.ClientRequest, config: ServerConfig); + + /** + * After inspecting the `request` properties, call this function on the + * request object to accept the connection. If you don't have a particular subprotocol + * you wish to speak, you may pass `null` for the `acceptedProtocol` parameter. + * + * @param [acceptedProtocol] case-insensitive value that was requested by the client + */ + accept(acceptedProtocol?: string, allowedOrigin?: string, cookies?: any[]): connection; + + /** + * Reject connection. + * You may optionally pass in an HTTP Status code (such as 404) and a textual + * description that will be sent to the client in the form of an + * `X-WebSocket-Reject-Reason` header. + */ + reject(httpStatus?: number, reason?: string); + + // Events + on(event: string, listener: Function): request; + on(event: 'requestAccepted', cb: (connection: connection) => void): request; + on(event: 'requestRejected', cb: () => void): request; + addListener(event: string, listener: Function): request; + addListener(event: 'requestAccepted', cb: (connection: connection) => void): request; + addListener(event: 'requestRejected', cb: () => void): request; + } + + class connection extends events.EventEmitter { + static CLOSE_REASON_NORMAL: number; + static CLOSE_REASON_GOING_AWAY: number; + static CLOSE_REASON_PROTOCOL_ERROR: number; + static CLOSE_REASON_UNPROCESSABLE_INPUT: number; + static CLOSE_REASON_RESERVED: number; + static CLOSE_REASON_NOT_PROVIDED: number; + static CLOSE_REASON_ABNORMAL: number; + static CLOSE_REASON_INVALID_DATA: number; + static CLOSE_REASON_POLICY_VIOLATION: number; + static CLOSE_REASON_MESSAGE_TOO_BIG: number; + static CLOSE_REASON_EXTENSION_REQUIRED: number; + + /** + * After the connection is closed, contains a textual description of the reason for + * the connection closure, or `null` if the connection is still open. + */ + closeDescription: string; + + /** + * After the connection is closed, contains the numeric close reason status code, + * or `-1` if the connection is still open. + */ + closeReasonCode: number; + + /** + * The subprotocol that was chosen to be spoken on this connection. This field + * will have been converted to lower case. + */ + protocol: string; + + socket: net.NodeSocket; + /** An array of extensions that were negotiated for this connection */ + extensions: any[]; + + /** + * The IP address of the remote peer as a string. In the case of a server, + * the `X-Forwarded-For` header will be respected and preferred for the purposes + * of populating this field. If you need to get to the actual remote IP address, + * `socket.remoteAddress` will provide it. + */ + remoteAddress: string; + + /** The version of the WebSocket protocol requested by the client */ + webSocketVersion: number; + /** Whether or not the connection is still connected. Read-only */ + connected: boolean; + + constructor(socket: net.NodeSocket, extensions: any[], protocol: string, + maskOutgoingPackets: boolean, config: ServerConfig); + + /** + * Close the connection. A close frame will be sent to the remote peer indicating + * that we wish to close the connection, and we will then wait for up to + * `config.closeTimeout` milliseconds for an acknowledgment from the remote peer + * before terminating the underlying socket connection. + */ + close(); + + /** + * Send a close frame to the remote peer and immediately close the socket without + * waiting for a response. This should generally be used only in error conditions. + */ + drop(reasonCode?: number, description?: string); + + /** + * Immediately sends the specified string as a UTF-8 WebSocket message to the remote + * peer. If `config.fragmentOutgoingMessages` is true the message may be sent as + * multiple fragments if it exceeds `config.fragmentationThreshold` bytes. + */ + sendUTF(data: {toString: (...args) => string}); + + + /** + * Immediately sends the specified Node Buffer object as a Binary WebSocket message + * to the remote peer. If config.fragmentOutgoingMessages is true the message may be + * sent as multiple fragments if it exceeds config.fragmentationThreshold bytes. + */ + sendBytes(buffer: NodeBuffer); + + /** Auto-detect the data type and send UTF-8 or Binary message */ + send(data: NodeBuffer); + send(data: {toString: (...args) => string}); + + /** Sends a ping frame. Ping frames must not exceed 125 bytes in length. */ + ping(data: NodeBuffer); + ping(data: {toString: (...args) => string}); + + /** + * Sends a pong frame. Pong frames may be sent unsolicited and such pong frames will + * trigger no action on the receiving peer. Pong frames sent in response to a ping + * frame must mirror the payload data of the ping frame exactly. + * The `connection` object handles this internally for you, so there should + * be no need to use this method to respond to pings. + * Pong frames must not exceed 125 bytes in length. + */ + pong(buffer: NodeBuffer); + + /** + * Serializes a `frame` object into binary data and immediately sends it to + * the remote peer. This is an advanced function, requiring you to manually compose + * your own `frame`. You should probably use sendUTF or sendBytes instead. + */ + sendFrame(frame: frame); + + // Events + on(event: string, listener: Function): connection; + on(event: 'message', cb: (msg: {type: string; utf8Data?: string; + binaryData?: NodeBuffer}) => void): connection; + on(event: 'frame', cb: (frame: frame) => void): connection; + on(event: 'close', cb: (code: number, desc: string) => void): connection; + on(event: 'error', cb: (err: Error) => void): connection; + addListener(event: string, listener: Function): connection; + addListener(event: 'message', cb: (msg: {type: string; utf8Data?: string; + binaryData?: NodeBuffer}) => void): connection; + addListener(event: 'frame', cb: (frame: frame) => void): connection; + addListener(event: 'close', cb: (code: number, desc: string) => void): connection; + addListener(event: 'error', cb: (err: Error) => void): connection; + } + + class frame { + /** Whether or not this is last frame in a fragmentation sequence */ + fin: boolean; + + /** + * Represents the RSV1 field in the framing. Setting this to true will result in + * a Protocol Error on the receiving peer. + */ + rsv1: boolean; + + /** + * Represents the RSV1 field in the framing. Setting this to true will result in + * a Protocol Error on the receiving peer. + */ + rsv2: boolean; + + /** + * Represents the RSV1 field in the framing. Setting this to true will result in + * a Protocol Error on the receiving peer. + */ + rsv3: boolean; + + /** + * Whether or not this frame is (or should be) masked. For outgoing frames, when + * connected as a client, this flag is automatically forced to true by `connection`. + * Outgoing frames sent from the server-side of a connection are not masked. + */ + mask: number; + + /** + * Identifies which kind of frame this is. + * + * Hex - Dec - Description + * 0x00 - 0 - Continuation + * 0x01 - 1 - Text Frame + * 0x02 - 2 - Binary Frame + * 0x08 - 8 - Close Frame + * 0x09 - 9 - Ping Frame + * 0x0A - 10 - Pong Frame + */ + opcode: number; + + /** + * Identifies the length of the payload data on a received frame. + * When sending a frame, will be automatically calculated from `binaryPayload` object. + */ + length: number; + + /** + * The binary payload data. + * Even text frames are sent with a Buffer providing the binary payload data. + */ + binaryPayload: NodeBuffer; + } + + export interface ClientConfig { + /** + * Which version of the WebSocket protocol to use when making the connection. + * Currently supported values are 8 and 13. This option will be removed once the + * protocol is finalized by the IETF It is only available to ease the transition + * through the intermediate draft protocol versions. The only thing this affects + * the name of the Origin header. + * @default 13 + */ + webSocketVersion: number; + + /** + * The maximum allowed received frame size in bytes. + * Single frame messages will also be limited to this maximum. + * @default 1MiB + */ + maxReceivedFrameSize: number; + + /** + * The maximum allowed aggregate message size (for fragmented messages) in bytes. + * @default 8MiB + */ + maxReceivedMessageSize: number; + + /** + * Whether or not to fragment outgoing messages. If true, messages will be + * automatically fragmented into chunks of up to `fragmentationThreshold` bytes. + * @default true + */ + fragmentOutgoingMessages: boolean; + + /** + * The maximum size of a frame in bytes before it is automatically fragmented. + * @default 16KiB + */ + fragmentationThreshold: number; + + /** + * If true, fragmented messages will be automatically assembled and the full message + * will be emitted via a `message` event. If false, each frame will be emitted on + * the `connection` object via a `frame` event and the application will be responsible + * for aggregating multiple fragmented frames. Single-frame messages will emit + * a `message` event in addition to the `frame` event. Most users will want to + * leave this set to true. + * @default true + */ + assembleFragments: boolean; + + /** + * The number of milliseconds to wait after sending a close frame for + * an acknowledgement to come back before giving up and just closing the socket. + * @default 5000 + */ + closeTimeout: number; + } + + class client extends events.EventEmitter { + constructor(clientConfig?: ClientConfig); + + /** + * Establish a connection. The remote server will select the best subprotocol that + * it supports and send that back when establishing the connection. + * + * @param [origin] can be used in user-agent scenarios to identify the page containing + * any scripting content that caused the connection to be requested. + * @param requestUrl should be a standard websocket url + */ + connect(requestUrl: url.Url, protocols?: string[], origin?: string, headers?: any[]); + connect(requestUrl: string, protocols?: string[], origin?: string, headers?: any[]); + connect(requestUrl: url.Url, protocols?: string, origin?: string, headers?: any[]); + connect(requestUrl: string, protocols?: string, origin?: string, headers?: any[]); + + // Events + on(event: string, listener: Function): client; + on(event: 'connect', cb: (connection: connection) => void): client; + on(event: 'connectFailed', cb: (err: Error) => void): client; + addListener(event: string, listener: Function): client; + addListener(event: 'connect', cb: (connection: connection) => void): client; + addListener(event: 'connectFailed', cb: (err: Error) => void): client; + } + + export var version: string; +} From baa029c0a37adb580dbc480587fd90593d1c12b6 Mon Sep 17 00:00:00 2001 From: Paul Loyd Date: Mon, 2 Dec 2013 13:34:02 +0400 Subject: [PATCH 2/2] Add support `--noImplicitAny`, rename interfaces --- websocket/websocket-tests.ts | 14 +++--- websocket/websocket.d.ts | 82 +++++++++++++++++++----------------- 2 files changed, 51 insertions(+), 45 deletions(-) diff --git a/websocket/websocket-tests.ts b/websocket/websocket-tests.ts index e91e8467d..7de0fa5b0 100644 --- a/websocket/websocket-tests.ts +++ b/websocket/websocket-tests.ts @@ -19,10 +19,10 @@ import http = require('http'); autoAcceptConnections: false }); - function originIsAllowed(origin) { return true; } + function originIsAllowed(origin: string) { return true; } wsServer.on('request', (request: websocket.request) => { - if (!originIsAllowed(request.origin)) { + if(!originIsAllowed(request.origin)) { request.reject(); console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.'); return; @@ -30,7 +30,7 @@ import http = require('http'); var connection = request.accept('echo-protocol', request.origin); console.log((new Date()) + ' Connection accepted.'); - connection.on('message', (message) => { + connection.on('message', (message: websocket.IMessage) => { if (message.type === 'utf8') { console.log('Received Message: ' + message.utf8Data); connection.sendUTF(message.utf8Data); @@ -41,8 +41,8 @@ import http = require('http'); } }); - connection.on('close', (reasonCode, description) => { - console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.'); + connection.on('close', (code: number) => { + console.log(Date.now() + ' Peer ' + connection.remoteAddress + ' disconnected.'); }); }); } @@ -57,7 +57,7 @@ import http = require('http'); client.on('connect', (connection: websocket.connection) => { console.log('WebSocket client connected'); - connection.on('error', (error) => { + connection.on('error', (error: Error) => { console.log("Connection Error: " + error.toString()); }); @@ -65,7 +65,7 @@ import http = require('http'); console.log('echo-protocol Connection Closed'); }); - connection.on('message', (message) => { + connection.on('message', (message: websocket.IMessage) => { if (message.type === 'utf8') { console.log("Received: '" + message.utf8Data + "'"); } diff --git a/websocket/websocket.d.ts b/websocket/websocket.d.ts index 5f378feb8..7dbd9a67c 100644 --- a/websocket/websocket.d.ts +++ b/websocket/websocket.d.ts @@ -11,7 +11,7 @@ declare module "websocket" { import net = require('net'); import url = require('url'); - export interface ServerConfig { + export interface IServerConfig { /** The http server instance to attach to */ httpServer: http.Server; @@ -107,29 +107,29 @@ declare module "websocket" { } export class server extends events.EventEmitter { - constructor(serverConfig?: ServerConfig); + constructor(serverConfig?: IServerConfig); /** Attach the `server` instance to a Node http.Server instance */ - mount(serverConfig: ServerConfig); + mount(serverConfig: IServerConfig): void; /** * Detach the `server` instance from the Node http.Server instance. * All existing connections are left alone and will not be affected, * but no new WebSocket connections will be accepted. */ - unmount(); + unmount(): void; /** Close all open WebSocket connections */ - closeAllConnections(); + closeAllConnections(): void; /** Close all open WebSocket connections and unmount the server */ - shutDown(); + shutDown(): void; // Events - on(event: string, listener: Function): server; + on(event: string, listener: () => void): server; on(event: 'request', cb: (request: request) => void): server; on(event: 'connect', cb: (connection: connection) => void): server; on(event: 'close', cb: (connection: connection, reason: number, desc: string) => void): server; - addListener(event: string, listener: Function): server; + addListener(event: string, listener: () => void): server; addListener(event: 'request', cb: (request: request) => void): server; addListener(event: 'connect', cb: (connection: connection) => void): server; addListener(event: 'close', cb: (connection: connection, reason: number, desc: string) => void): server; @@ -172,7 +172,7 @@ declare module "websocket" { */ requestedProtocols: string[]; - constructor(socket: net.NodeSocket, httpRequest: http.ClientRequest, config: ServerConfig); + constructor(socket: net.NodeSocket, httpRequest: http.ClientRequest, config: IServerConfig); /** * After inspecting the `request` properties, call this function on the @@ -189,17 +189,23 @@ declare module "websocket" { * description that will be sent to the client in the form of an * `X-WebSocket-Reject-Reason` header. */ - reject(httpStatus?: number, reason?: string); + reject(httpStatus?: number, reason?: string): void; // Events - on(event: string, listener: Function): request; + on(event: string, listener: () => void): request; on(event: 'requestAccepted', cb: (connection: connection) => void): request; on(event: 'requestRejected', cb: () => void): request; - addListener(event: string, listener: Function): request; + addListener(event: string, listener: () => void): request; addListener(event: 'requestAccepted', cb: (connection: connection) => void): request; addListener(event: 'requestRejected', cb: () => void): request; } + export interface IMessage { + type: string; + utf8Data?: string; + binaryData?: NodeBuffer; + } + class connection extends events.EventEmitter { static CLOSE_REASON_NORMAL: number; static CLOSE_REASON_GOING_AWAY: number; @@ -249,7 +255,7 @@ declare module "websocket" { connected: boolean; constructor(socket: net.NodeSocket, extensions: any[], protocol: string, - maskOutgoingPackets: boolean, config: ServerConfig); + maskOutgoingPackets: boolean, config: IServerConfig); /** * Close the connection. A close frame will be sent to the remote peer indicating @@ -257,36 +263,35 @@ declare module "websocket" { * `config.closeTimeout` milliseconds for an acknowledgment from the remote peer * before terminating the underlying socket connection. */ - close(); + close(): void; /** * Send a close frame to the remote peer and immediately close the socket without * waiting for a response. This should generally be used only in error conditions. */ - drop(reasonCode?: number, description?: string); + drop(reasonCode?: number, description?: string): void; /** * Immediately sends the specified string as a UTF-8 WebSocket message to the remote * peer. If `config.fragmentOutgoingMessages` is true the message may be sent as * multiple fragments if it exceeds `config.fragmentationThreshold` bytes. */ - sendUTF(data: {toString: (...args) => string}); - + sendUTF(data: {toString: (...args: any[]) => string}): void; /** * Immediately sends the specified Node Buffer object as a Binary WebSocket message * to the remote peer. If config.fragmentOutgoingMessages is true the message may be * sent as multiple fragments if it exceeds config.fragmentationThreshold bytes. */ - sendBytes(buffer: NodeBuffer); + sendBytes(buffer: NodeBuffer): void; /** Auto-detect the data type and send UTF-8 or Binary message */ - send(data: NodeBuffer); - send(data: {toString: (...args) => string}); + send(data: NodeBuffer): void; + send(data: {toString: (...args: any[]) => string}): void; /** Sends a ping frame. Ping frames must not exceed 125 bytes in length. */ - ping(data: NodeBuffer); - ping(data: {toString: (...args) => string}); + ping(data: NodeBuffer): void; + ping(data: {toString: (...args: any[]) => string}): void; /** * Sends a pong frame. Pong frames may be sent unsolicited and such pong frames will @@ -296,25 +301,23 @@ declare module "websocket" { * be no need to use this method to respond to pings. * Pong frames must not exceed 125 bytes in length. */ - pong(buffer: NodeBuffer); + pong(buffer: NodeBuffer): void; /** * Serializes a `frame` object into binary data and immediately sends it to * the remote peer. This is an advanced function, requiring you to manually compose * your own `frame`. You should probably use sendUTF or sendBytes instead. */ - sendFrame(frame: frame); + sendFrame(frame: frame): void; // Events - on(event: string, listener: Function): connection; - on(event: 'message', cb: (msg: {type: string; utf8Data?: string; - binaryData?: NodeBuffer}) => void): connection; + on(event: string, listener: () => void): connection; + on(event: 'message', cb: (data: IMessage) => void): connection; on(event: 'frame', cb: (frame: frame) => void): connection; on(event: 'close', cb: (code: number, desc: string) => void): connection; on(event: 'error', cb: (err: Error) => void): connection; - addListener(event: string, listener: Function): connection; - addListener(event: 'message', cb: (msg: {type: string; utf8Data?: string; - binaryData?: NodeBuffer}) => void): connection; + addListener(event: string, listener: () => void): connection; + addListener(event: 'message', cb: (data: IMessage) => void): connection; addListener(event: 'frame', cb: (frame: frame) => void): connection; addListener(event: 'close', cb: (code: number, desc: string) => void): connection; addListener(event: 'error', cb: (err: Error) => void): connection; @@ -375,7 +378,7 @@ declare module "websocket" { binaryPayload: NodeBuffer; } - export interface ClientConfig { + export interface IClientConfig { /** * Which version of the WebSocket protocol to use when making the connection. * Currently supported values are 8 and 13. This option will be removed once the @@ -432,7 +435,7 @@ declare module "websocket" { } class client extends events.EventEmitter { - constructor(clientConfig?: ClientConfig); + constructor(clientConfig?: IClientConfig); /** * Establish a connection. The remote server will select the best subprotocol that @@ -442,19 +445,22 @@ declare module "websocket" { * any scripting content that caused the connection to be requested. * @param requestUrl should be a standard websocket url */ - connect(requestUrl: url.Url, protocols?: string[], origin?: string, headers?: any[]); - connect(requestUrl: string, protocols?: string[], origin?: string, headers?: any[]); - connect(requestUrl: url.Url, protocols?: string, origin?: string, headers?: any[]); - connect(requestUrl: string, protocols?: string, origin?: string, headers?: any[]); + connect(requestUrl: url.Url, protocols?: string[], origin?: string, headers?: any[]): void; + connect(requestUrl: string, protocols?: string[], origin?: string, headers?: any[]): void; + connect(requestUrl: url.Url, protocols?: string, origin?: string, headers?: any[]): void; + connect(requestUrl: string, protocols?: string, origin?: string, headers?: any[]): void; // Events - on(event: string, listener: Function): client; + on(event: string, listener: () => void): client; on(event: 'connect', cb: (connection: connection) => void): client; on(event: 'connectFailed', cb: (err: Error) => void): client; - addListener(event: string, listener: Function): client; + addListener(event: string, listener: () => void): client; addListener(event: 'connect', cb: (connection: connection) => void): client; addListener(event: 'connectFailed', cb: (err: Error) => void): client; } export var version: string; + export var constants: { + DEBUG: boolean; + }; }