From 5ee939e087ba1e0c4966002a007115f856ecb29e Mon Sep 17 00:00:00 2001 From: Daniel Rose Date: Fri, 12 Apr 2019 13:27:41 +0200 Subject: [PATCH 1/2] Add missing server-side-socket events. The events can be subscribed (on), unsubscribed (off) or subscribed for one call only (once). Also, custom events are allowed. --- .../socketcluster-server/scserversocket.d.ts | 19 +++++ .../socketcluster-server-tests.ts | 81 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/types/socketcluster-server/scserversocket.d.ts b/types/socketcluster-server/scserversocket.d.ts index 00eaa03c90..f7af9e16f6 100644 --- a/types/socketcluster-server/scserversocket.d.ts +++ b/types/socketcluster-server/scserversocket.d.ts @@ -29,6 +29,7 @@ declare class SCServerSocket extends Emitter { constructor(id: string, server: SCServer, socket: WebSocket); + on(event: string, listener: SCServerSocket.AnyFunction): this; on(event: "error", listener: (error: Error) => void): this; on(event: "message" | "raw", listener: (message: WebSocket.Data) => void): this; on(event: "connectAbort" | "disconnect" | "close", listener: (code: number, data?: any) => void): this; @@ -36,6 +37,22 @@ declare class SCServerSocket extends Emitter { on(event: "authenticate", listener: (authToken?: SCServer.AuthToken) => void): this; on(event: "deauthenticate", listener: (oldToken?: SCServer.AuthToken) => void): this; + once(event: string, listener: SCServerSocket.AnyFunction): this; + once(event: "error", listener: (error: Error) => void): this; + once(event: "message" | "raw", listener: (message: WebSocket.Data) => void): this; + once(event: "connectAbort" | "disconnect" | "close", listener: (code: number, data?: any) => void): this; + once(event: "authStateChange", listener: (stateChangeData: SCServerSocket.StateChangeData) => void): this; + once(event: "authenticate", listener: (authToken?: SCServer.AuthToken) => void): this; + once(event: "deauthenticate", listener: (oldToken?: SCServer.AuthToken) => void): this; + + off(event?: string, listener?: SCServerSocket.AnyFunction): this; + off(event: "error", listener?: (error: Error) => void): this; + off(event: "message" | "raw", listener?: (message: WebSocket.Data) => void): this; + off(event: "connectAbort" | "disconnect" | "close", listener?: (code: number, data?: any) => void): this; + off(event: "authStateChange", listener?: (stateChangeData: SCServerSocket.StateChangeData) => void): this; + off(event: "authenticate", listener?: (authToken?: SCServer.AuthToken) => void): this; + off(event: "deauthenticate", listener?: (oldToken?: SCServer.AuthToken) => void): this; + getState(): "connecting" | "open" | "closed"; getBytesReceived(): number; @@ -72,6 +89,8 @@ declare class SCServerSocket extends Emitter { export = SCServerSocket; declare namespace SCServerSocket { + type AnyFunction = (...args: any[]) => any; + type EmitCallback = (err: Error, eventObject: EventObject) => void; interface EventObject { diff --git a/types/socketcluster-server/socketcluster-server-tests.ts b/types/socketcluster-server/socketcluster-server-tests.ts index 3d62fe9041..082410e1ce 100644 --- a/types/socketcluster-server/socketcluster-server-tests.ts +++ b/types/socketcluster-server/socketcluster-server-tests.ts @@ -3,6 +3,7 @@ // Using with basic http(s) module (example) import http = require("http"); +import WebSocket = require("ws"); import * as socketClusterServer from "socketcluster-server"; let httpServer = http.createServer(); @@ -37,3 +38,83 @@ scServer.on("connection", socket => { }); httpServer.listen(8000); + +// Tests of the server-side socket + +scServer.on("connection", socket => { + // Check the standard events, with normal subscription, + // one-time subscription and unsubscription. + + const errorListener: (error: Error) => void = err => { + console.log(err); + }; + socket.on("error", errorListener); + socket.once("error", errorListener); + socket.off("error", errorListener); + socket.off("error"); + + const messageListener: (message: WebSocket.Data) => void = message => { + console.log(message); + }; + socket.on("message", messageListener); + socket.once("message", messageListener); + socket.off("message", messageListener); + socket.off("message"); + + socket.on("raw", messageListener); + socket.once("raw", messageListener); + socket.off("raw", messageListener); + socket.off("raw"); + + const closeListener: (code: number, data?: any) => void = (code, data) => { + console.log(`${code} ${data}`); + }; + socket.on("connectAbort", closeListener); + socket.once("connectAbort", closeListener); + socket.off("connectAbort", closeListener); + socket.off("connectAbort"); + + socket.on("disconnect", closeListener); + socket.once("disconnect", closeListener); + socket.off("disconnect", closeListener); + socket.off("disconnect"); + + socket.on("close", closeListener); + socket.once("close", closeListener); + socket.off("close", closeListener); + socket.off("close"); + + const authStateChangeListener: (stateChangeData: socketClusterServer.SCServerSocket.StateChangeData) => void = data => { + console.log(data); + }; + socket.on("authStateChange", authStateChangeListener); + socket.once("authStateChange", authStateChangeListener); + socket.off("authStateChange", authStateChangeListener); + socket.off("authStateChange"); + + const authenticateListener: (authToken?: socketClusterServer.SCServer.AuthToken) => void = authToken => { + console.log(authToken); + }; + socket.on("authenticate", authenticateListener); + socket.once("authenticate", authenticateListener); + socket.off("authenticate", authenticateListener); + socket.off("authenticate"); + + const deauthenticateListener: (oldToken?: socketClusterServer.SCServer.AuthToken) => void = oldToken => { + console.log(oldToken); + }; + socket.on("deauthenticate", deauthenticateListener); + socket.once("deauthenticate", deauthenticateListener); + socket.off("deauthenticate", deauthenticateListener); + socket.off("deauthenticate"); + + // Check custom events, with normal subscription, + // one-time subscription and unsubscription. + const customEventListener: (data?: any) => void = data => { + console.log(data); + }; + socket.on("custom-event", customEventListener); + socket.once("custom-event", customEventListener); + socket.off("custom-event", customEventListener); + socket.off("custom-event"); +}); From af69548da480880f254ee74209f6879ff6839b9c Mon Sep 17 00:00:00 2001 From: Daniel Rose Date: Fri, 12 Apr 2019 14:27:29 +0200 Subject: [PATCH 2/2] Callbacks are optional. --- types/sc-broker-cluster/index.d.ts | 14 +++---- .../sc-broker-cluster-tests.ts | 39 +++++++++++++++++-- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/types/sc-broker-cluster/index.d.ts b/types/sc-broker-cluster/index.d.ts index b63b0afbea..9796797005 100644 --- a/types/sc-broker-cluster/index.d.ts +++ b/types/sc-broker-cluster/index.d.ts @@ -69,9 +69,9 @@ export type mapperFunction = (keyChain: KeyChain, method: string, clientIds: num export class SCExchange extends AbstractDataClient { constructor(privateClientCluster: ClientCluster, publicClientCluster: ClientCluster, ioClusterClient: Client); - send(data: any, mapIndex: number | string | string[] | null, callback?: (err?: Error) => void): void; + send(data: any, mapIndex: number | string | string[] | null, callback?: AsyncResultArrayCallback): void; - publish(channelName: string, data: any, callback: (err?: Error) => void): void; + publish(channelName: string, data: any, callback?: (err?: Error) => void): void; subscribe(channelName: string): SCChannel; unsubscribe(channelName: string): void; @@ -146,12 +146,12 @@ export class Client extends EventEmitter { on(event: "ready", listener: () => void): this; on(event: "message", listener: (packet: MessagePacket) => void): this; - destroy(callback: AsyncResultArrayCallback): void; + destroy(callback?: AsyncResultArrayCallback): void; - subscribe(channel: string, callback: (err?: Error) => void): void; - unsubscribe(channel: string, callback: () => void): void; - unsubscribeAll(callback: () => void): void; - isSubscribed(channel: string, includePending: boolean): boolean; + subscribe(channel: string, callback?: (err?: Error) => void): void; + unsubscribe(channel: string, callback?: () => void): void; + unsubscribeAll(callback?: AsyncResultArrayCallback): void; + isSubscribed(channel: string, includePending?: boolean): boolean; subscribeSocket(socket: SCServerSocket, channel: string, callback?: (err?: Error) => void): void; unsubscribeSocket(socket: SCServerSocket, channel: string, callback?: () => void): void; diff --git a/types/sc-broker-cluster/sc-broker-cluster-tests.ts b/types/sc-broker-cluster/sc-broker-cluster-tests.ts index 0f5c274248..8abac30739 100644 --- a/types/sc-broker-cluster/sc-broker-cluster-tests.ts +++ b/types/sc-broker-cluster/sc-broker-cluster-tests.ts @@ -2,6 +2,8 @@ import { Client } from "sc-broker-cluster"; import { SCServer, SCServerSocket } from "socketcluster-server"; import WebSocket = require("ws"); +// Client tests + const client = new Client({ brokers: [], secretKey: "secretKey", @@ -12,18 +14,47 @@ const client = new Client({ client.on("error", err => {}); client.on("warning", err => {}); -const exchange = client.exchange(); - const scServer = new SCServer(); client.setSCServer(scServer); client.once("ready", () => {}); +client.subscribe("channel"); +client.subscribe("channel", () => {}); +client.subscribe("channel", err => {}); + +client.unsubscribe("channel"); +client.unsubscribe("channel", () => {}); + +client.unsubscribeAll(); +client.unsubscribeAll(() => {}); +client.unsubscribeAll(err => {}); +client.unsubscribeAll((err, results) => {}); + +client.isSubscribed("channel"); +client.isSubscribed("channel", true); + const wsSocket = new WebSocket("address"); const socket = new SCServerSocket("id", scServer, wsSocket); +client.subscribeSocket(socket, "channelName"); client.subscribeSocket(socket, "channelName", err => {}); client.unsubscribeSocket(socket, "channelName"); +client.unsubscribeSocket(socket, "channelName", () => {}); -const data: any = {}; -exchange.publish("channelName", data, err => {}); +client.destroy(); +client.destroy(() => {}); +client.destroy(err => {}); +client.destroy((err, results) => {}); + +// SCExchange tests + +const exchange = client.exchange(); + +exchange.send({}, null); +exchange.send("dummy", 1, () => {}); +exchange.send("dummy", ["1", "2"], err => {}); +exchange.send(123, "*", (err, results) => {}); + +exchange.publish("channelName", {}, err => {}); +exchange.publish("channelName", {});