From e4c1b888ca65045e8ecde700c8289192e6eb5fc0 Mon Sep 17 00:00:00 2001 From: Pawel Kadluczka Date: Mon, 21 Aug 2017 17:51:24 -0700 Subject: [PATCH] Adding loggers to TS client --- .../HttpConnection.ts | 18 +++--- .../HubConnection.ts | 16 +++-- .../IHttpConnectionOptions.ts | 2 + .../ILogger.ts | 10 ++++ .../Loggers.ts | 20 +++++++ .../Transports.ts | 31 ++++++---- .../index.ts | 1 + .../wwwroot/js/connectionTests.js | 6 +- .../wwwroot/js/hubConnectionTests.js | 58 ++++++++++++++----- 9 files changed, 124 insertions(+), 38 deletions(-) create mode 100644 client-ts/Microsoft.AspNetCore.SignalR.Client.TS/ILogger.ts create mode 100644 client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Loggers.ts diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HttpConnection.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HttpConnection.ts index 38854dab8a..7eb6472dc7 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HttpConnection.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HttpConnection.ts @@ -3,6 +3,8 @@ import { IConnection } from "./IConnection" import { ITransport, TransferMode, TransportType, WebSocketTransport, ServerSentEventsTransport, LongPollingTransport } from "./Transports" import { IHttpClient, HttpClient } from "./HttpClient" import { IHttpConnectionOptions } from "./IHttpConnectionOptions" +import { ILogger, LogLevel } from "./ILogger" +import { NullLogger } from "./Loggers" const enum ConnectionState { Initial, @@ -19,10 +21,11 @@ interface INegotiateResponse { export class HttpConnection implements IConnection { private connectionState: ConnectionState; private url: string; - private connectionId: string; - private httpClient: IHttpClient; + private readonly httpClient: IHttpClient; + private readonly logger: ILogger; + private readonly options: IHttpConnectionOptions; private transport: ITransport; - private options: IHttpConnectionOptions; + private connectionId: string; private startPromise: Promise; readonly features: any = {}; @@ -30,6 +33,7 @@ export class HttpConnection implements IConnection { constructor(url: string, options: IHttpConnectionOptions = {}) { this.url = url; this.httpClient = options.httpClient || new HttpClient(); + this.logger = options.logger || new NullLogger(); this.connectionState = ConnectionState.Initial; this.options = options; } @@ -74,7 +78,7 @@ export class HttpConnection implements IConnection { this.changeState(ConnectionState.Connecting, ConnectionState.Connected); } catch (e) { - console.log("Failed to start the connection. " + e); + this.logger.log(LogLevel.Error, "Failed to start the connection. " + e); this.connectionState = ConnectionState.Disconnected; this.transport = null; throw e; @@ -86,13 +90,13 @@ export class HttpConnection implements IConnection { transport = TransportType[availableTransports[0]]; } if (transport === TransportType.WebSockets && availableTransports.indexOf(TransportType[transport]) >= 0) { - return new WebSocketTransport(); + return new WebSocketTransport(this.logger); } if (transport === TransportType.ServerSentEvents && availableTransports.indexOf(TransportType[transport]) >= 0) { - return new ServerSentEventsTransport(this.httpClient); + return new ServerSentEventsTransport(this.httpClient, this.logger); } if (transport === TransportType.LongPolling && availableTransports.indexOf(TransportType[transport]) >= 0) { - return new LongPollingTransport(this.httpClient); + return new LongPollingTransport(this.httpClient, this.logger); } if (this.isITransport(transport)) { diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HubConnection.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HubConnection.ts index c7d11921c6..e8a5ae87e8 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HubConnection.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/HubConnection.ts @@ -6,21 +6,27 @@ import { IHubProtocol, ProtocolType, MessageType, HubMessage, CompletionMessage, import { JsonHubProtocol } from "./JsonHubProtocol"; import { TextMessageFormat } from "./Formatters" import { Base64EncodedHubProtocol } from "./Base64EncodedHubProtocol" +import { ILogger, LogLevel } from "./ILogger" +import { NullLogger } from "./Loggers" export { TransportType } from "./Transports" export { HttpConnection } from "./HttpConnection" export { JsonHubProtocol } from "./JsonHubProtocol" +export { LogLevel } from "./ILogger" +export { ConsoleLogger } from "./Loggers" export class HubConnection { - private connection: IConnection; + private readonly connection: IConnection; + private readonly logger: ILogger; + private protocol: IHubProtocol; private callbacks: Map void>; private methods: Map void>; private id: number; private connectionClosedCallback: ConnectionClosed; - private protocol: IHubProtocol; - constructor(connection: IConnection, protocol: IHubProtocol = new JsonHubProtocol()) { + constructor(connection: IConnection, logger: ILogger = new NullLogger(), protocol: IHubProtocol = new JsonHubProtocol()) { this.connection = connection; + this.logger = logger || new NullLogger(); this.protocol = protocol || new JsonHubProtocol(); this.connection.onDataReceived = data => { this.onDataReceived(data); @@ -57,7 +63,7 @@ export class HubConnection { } break; default: - console.log("Invalid message type: " + data); + this.logger.log(LogLevel.Warning, "Invalid message type: " + data); break; } } @@ -72,7 +78,7 @@ export class HubConnection { } } else { - console.log(`No client method with the name '${invocationMessage.target}' found.`); + this.logger.log(LogLevel.Warning, `No client method with the name '${invocationMessage.target}' found.`); } } diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/IHttpConnectionOptions.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/IHttpConnectionOptions.ts index 2ddb45a2ee..0a25deb282 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/IHttpConnectionOptions.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/IHttpConnectionOptions.ts @@ -1,7 +1,9 @@ import { IHttpClient } from "./HttpClient" import { TransportType, ITransport } from "./Transports" +import { ILogger } from "./ILogger"; export interface IHttpConnectionOptions { httpClient?: IHttpClient; transport?: TransportType | ITransport; + logger?: ILogger; } diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/ILogger.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/ILogger.ts new file mode 100644 index 0000000000..099b8e6e94 --- /dev/null +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/ILogger.ts @@ -0,0 +1,10 @@ +export enum LogLevel { + Information = 0, + Warning, + Error, + None +} + +export interface ILogger { + log(logLevel: LogLevel, message: string): void; +} \ No newline at end of file diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Loggers.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Loggers.ts new file mode 100644 index 0000000000..add985647d --- /dev/null +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Loggers.ts @@ -0,0 +1,20 @@ +import { ILogger, LogLevel } from "./ILogger" + +export class NullLogger implements ILogger { + log(logLevel: LogLevel, message: string): void { + } +} + +export class ConsoleLogger implements ILogger { + private readonly minimumLogLevel: LogLevel; + + constructor(minimumLogLevel: LogLevel) { + this.minimumLogLevel = minimumLogLevel; + } + + log(logLevel: LogLevel, message: string): void { + if (logLevel >= this.minimumLogLevel) { + console.log(`${LogLevel[logLevel]}: ${message}`); + } + } +} \ No newline at end of file diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Transports.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Transports.ts index 6dca4289ce..25c89be3c4 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Transports.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/Transports.ts @@ -1,6 +1,7 @@ import { DataReceived, TransportClosed } from "./Common" import { IHttpClient } from "./HttpClient" import { HttpError } from "./HttpError" +import { ILogger, LogLevel } from "./ILogger" export enum TransportType { WebSockets, @@ -22,8 +23,13 @@ export interface ITransport { } export class WebSocketTransport implements ITransport { + private readonly logger: ILogger; private webSocket: WebSocket; + constructor(logger: ILogger) { + this.logger = logger; + } + connect(url: string, requestedTransferMode: TransferMode): Promise { return new Promise((resolve, reject) => { @@ -35,7 +41,7 @@ export class WebSocketTransport implements ITransport { } webSocket.onopen = (event: Event) => { - console.log(`WebSocket connected to ${url}`); + this.logger.log(LogLevel.Information, `WebSocket connected to ${url}`); this.webSocket = webSocket; resolve(requestedTransferMode); }; @@ -45,7 +51,7 @@ export class WebSocketTransport implements ITransport { }; webSocket.onmessage = (message: MessageEvent) => { - console.log(`(WebSockets transport) data received: ${message.data}`); + this.logger.log(LogLevel.Information, `(WebSockets transport) data received: ${message.data}`); if (this.onDataReceived) { this.onDataReceived(message.data); } @@ -86,12 +92,14 @@ export class WebSocketTransport implements ITransport { } export class ServerSentEventsTransport implements ITransport { + private readonly httpClient: IHttpClient; + private readonly logger: ILogger; private eventSource: EventSource; private url: string; - private httpClient: IHttpClient; - constructor(httpClient: IHttpClient) { + constructor(httpClient: IHttpClient, logger: ILogger) { this.httpClient = httpClient; + this.logger = logger; } connect(url: string, requestedTransferMode: TransferMode): Promise { @@ -107,7 +115,7 @@ export class ServerSentEventsTransport implements ITransport { eventSource.onmessage = (e: MessageEvent) => { if (this.onDataReceived) { try { - console.log(`(SSE transport) data received: ${e.data}`); + this.logger.log(LogLevel.Information, `(SSE transport) data received: ${e.data}`); this.onDataReceived(e.data); } catch (error) { if (this.onClosed) { @@ -128,7 +136,7 @@ export class ServerSentEventsTransport implements ITransport { } eventSource.onopen = () => { - console.log(`SSE connected to ${this.url}`); + this.logger.log(LogLevel.Information, `SSE connected to ${this.url}`); this.eventSource = eventSource; // SSE is a text protocol resolve(TransferMode.Text); @@ -156,13 +164,16 @@ export class ServerSentEventsTransport implements ITransport { } export class LongPollingTransport implements ITransport { + private readonly httpClient: IHttpClient; + private readonly logger: ILogger; + private url: string; - private httpClient: IHttpClient; private pollXhr: XMLHttpRequest; private shouldPoll: boolean; - constructor(httpClient: IHttpClient) { + constructor(httpClient: IHttpClient, logger: ILogger) { this.httpClient = httpClient; + this.logger = logger; } connect(url: string, requestedTransferMode: TransferMode): Promise { @@ -187,11 +198,11 @@ export class LongPollingTransport implements ITransport { if (this.onDataReceived) { try { if (pollXhr.response) { - console.log(`(LongPolling transport) data received: ${pollXhr.response}`); + this.logger.log(LogLevel.Information, `(LongPolling transport) data received: ${pollXhr.response}`); this.onDataReceived(pollXhr.response); } else { - console.log(`(LongPolling transport) timed out`); + this.logger.log(LogLevel.Information, "(LongPolling transport) timed out"); } } catch (error) { if (this.onClosed) { diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/index.ts b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/index.ts index 1672e17870..d9530f35e5 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/index.ts +++ b/client-ts/Microsoft.AspNetCore.SignalR.Client.TS/index.ts @@ -3,4 +3,5 @@ export * from "./HttpConnection" export * from "./HttpClient" export * from "./HubConnection" export * from "./Transports" +export * from "./Loggers" diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/connectionTests.js b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/connectionTests.js index 314ce39614..b9f782ad66 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/connectionTests.js +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/connectionTests.js @@ -29,7 +29,11 @@ describe('connection', () => { eachTransport(transportType => { it(`over ${signalR.TransportType[transportType]} can send and receive messages`, done => { const message = "Hello World!"; - let connection = new signalR.HttpConnection(ECHOENDPOINT_URL, { transport: transportType }); + let connection = new signalR.HttpConnection(ECHOENDPOINT_URL, + { + transport: transportType, + logger: new signalR.ConsoleLogger(signalR.LogLevel.Information) + }); let received = ""; connection.onDataReceived = data => { diff --git a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js index a66ef4ea45..d501b910c7 100644 --- a/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js +++ b/client-ts/Microsoft.AspNetCore.SignalR.Test.Server/wwwroot/js/hubConnectionTests.js @@ -5,8 +5,12 @@ describe('hubConnection', () => { describe(`${protocol.name} over ${signalR.TransportType[transportType]} transport`, () => { it(`can invoke server method and receive result`, done => { const message = "你好,世界!"; - let hubConnection = new signalR.HubConnection( - new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType }), protocol); + let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( + TESTHUBENDPOINT_URL, + { transport: transportType, logger: logger }), + logger, + protocol); hubConnection.onClosed = error => { expect(error).toBe(undefined); done(); @@ -32,8 +36,13 @@ describe('hubConnection', () => { }); it(`can stream server method and receive result`, done => { - let hubConnection = new signalR.HubConnection( - new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType }), protocol); + let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( + TESTHUBENDPOINT_URL, + { transport: transportType, logger: logger }), + logger, + protocol); + hubConnection.onClosed = error => { expect(error).toBe(undefined); done(); @@ -65,8 +74,13 @@ describe('hubConnection', () => { it(`rethrows an exception from the server when invoking`, done => { const errorMessage = "An error occurred."; - let hubConnection = new signalR.HubConnection( - new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType }), protocol); + + let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( + TESTHUBENDPOINT_URL, + { transport: transportType, logger: logger }), + logger, + protocol); hubConnection.start() .then(() => { @@ -93,8 +107,13 @@ describe('hubConnection', () => { it(`rethrows an exception from the server when streaming`, done => { const errorMessage = "An error occurred."; - let hubConnection = new signalR.HubConnection( - new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType }), protocol); + + let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( + TESTHUBENDPOINT_URL, + { transport: transportType, logger: logger }), + logger, + protocol); hubConnection.start() .then(() => { @@ -120,20 +139,25 @@ describe('hubConnection', () => { }); it(`can receive server calls`, done => { - let client = new signalR.HubConnection( - new signalR.HttpConnection(TESTHUBENDPOINT_URL, { transport: transportType }), protocol); + let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( + TESTHUBENDPOINT_URL, + { transport: transportType, logger: logger }), + logger, + protocol); + const message = "你好 SignalR!"; let callbackPromise = new Promise((resolve, reject) => { - client.on("Message", msg => { + hubConnection.on("Message", msg => { expect(msg).toBe(message); resolve(); }); }); - client.start() + hubConnection.start() .then(() => { - return Promise.all([client.invoke('InvokeWithString', message), callbackPromise]); + return Promise.all([hubConnection.invoke('InvokeWithString', message), callbackPromise]); }) .then(() => { return stop(); @@ -154,8 +178,12 @@ describe('hubConnection', () => { ServerSentEvents: "Error occurred" }; - let hubConnection = new signalR.HubConnection( - new signalR.HttpConnection(`http://${document.location.host}/uncreatable`, { transport: transportType }), protocol); + let logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); + let hubConnection = new signalR.HubConnection(new signalR.HttpConnection( + `http://${document.location.host}/uncreatable`, + { transport: transportType, logger: logger }), + logger, + protocol); hubConnection.onClosed = error => { expect(error.message).toMatch(errorRegex[signalR.TransportType[transportType]]);