Introducing the IConnection interface

Unifying events
This commit is contained in:
moozzyk 2017-03-20 14:33:13 -07:00 committed by Pawel Kadluczka
parent 14d3f2bc9b
commit 70e4ec9a06
7 changed files with 41 additions and 25 deletions

View File

@ -1,4 +1,5 @@
import { DataReceived, ConnectionClosed } from "./Common" import { DataReceived, ConnectionClosed } from "./Common"
import { IConnection } from "./IConnection"
import { ITransport, WebSocketTransport, ServerSentEventsTransport, LongPollingTransport } from "./Transports" import { ITransport, WebSocketTransport, ServerSentEventsTransport, LongPollingTransport } from "./Transports"
import { IHttpClient, HttpClient } from "./HttpClient" import { IHttpClient, HttpClient } from "./HttpClient"
import { ISignalROptions } from "./ISignalROptions" import { ISignalROptions } from "./ISignalROptions"
@ -9,15 +10,13 @@ enum ConnectionState {
Connected Connected
} }
export class Connection { export class Connection implements IConnection {
private connectionState: ConnectionState; private connectionState: ConnectionState;
private url: string; private url: string;
private queryString: string; private queryString: string;
private connectionId: string; private connectionId: string;
private httpClient: IHttpClient; private httpClient: IHttpClient;
private transport: ITransport; private transport: ITransport;
private dataReceivedCallback: DataReceived = (data: any) => { };
private connectionClosedCallback: ConnectionClosed = (error?: any) => { };
constructor(url: string, queryString: string = "", options: ISignalROptions = {}) { constructor(url: string, queryString: string = "", options: ISignalROptions = {}) {
this.url = url; this.url = url;
@ -32,7 +31,7 @@ export class Connection {
} }
this.transport = this.createTransport(transportName); this.transport = this.createTransport(transportName);
this.transport.onDataReceived = this.dataReceivedCallback; this.transport.onDataReceived = this.onDataReceived;
this.transport.onClosed = e => this.stopConnection(e); this.transport.onClosed = e => this.stopConnection(e);
try { try {
@ -82,14 +81,12 @@ export class Connection {
this.transport.stop(); this.transport.stop();
this.transport = null; this.transport = null;
this.connectionState = ConnectionState.Disconnected; this.connectionState = ConnectionState.Disconnected;
this.connectionClosedCallback(error);
if (this.onClosed) {
this.onClosed(error);
}
} }
set dataReceived(callback: DataReceived) { onDataReceived: DataReceived;
this.dataReceivedCallback = callback; onClosed: ConnectionClosed;
}
set connectionClosed(callback: ConnectionClosed) {
this.connectionClosedCallback = callback;
}
} }

View File

@ -1,4 +1,5 @@
import { ConnectionClosed } from "./Common" import { ConnectionClosed } from "./Common"
import { IConnection } from "./IConnection"
import { Connection } from "./Connection" import { Connection } from "./Connection"
interface InvocationDescriptor { interface InvocationDescriptor {
@ -16,16 +17,21 @@ interface InvocationResultDescriptor {
export { Connection } from "./Connection" export { Connection } from "./Connection"
export class HubConnection { export class HubConnection {
private connection: Connection; private connection: IConnection;
private callbacks: Map<string, (invocationDescriptor: InvocationResultDescriptor) => void>; private callbacks: Map<string, (invocationDescriptor: InvocationResultDescriptor) => void>;
private methods: Map<string, (...args: any[]) => void>; private methods: Map<string, (...args: any[]) => void>;
private id: number; private id: number;
constructor(url: string, queryString?: string) { static create(url: string, queryString?: string): HubConnection {
this.connection = new Connection(url, queryString); return new this(new Connection(url, queryString))
}
this.connection.dataReceived = data => { constructor(connection: IConnection);
this.dataReceived(data); constructor(url: string, queryString?: string);
constructor(connectionOrUrl: IConnection | string, queryString?: string) {
this.connection = typeof connectionOrUrl === "string" ? new Connection(connectionOrUrl, queryString) : connectionOrUrl;
this.connection.onDataReceived = data => {
this.onDataReceived(data);
}; };
this.callbacks = new Map<string, (invocationDescriptor: InvocationResultDescriptor) => void>(); this.callbacks = new Map<string, (invocationDescriptor: InvocationResultDescriptor) => void>();
@ -33,7 +39,7 @@ export class HubConnection {
this.id = 0; this.id = 0;
} }
private dataReceived(data: any) { private onDataReceived(data: any) {
// TODO: separate JSON parsing // TODO: separate JSON parsing
// Can happen if a poll request was cancelled // Can happen if a poll request was cancelled
if (!data) { if (!data) {
@ -101,7 +107,7 @@ export class HubConnection {
this.methods[methodName] = method; this.methods[methodName] = method;
} }
set connectionClosed(callback: ConnectionClosed) { set onClosed(callback: ConnectionClosed) {
this.connection.connectionClosed = callback; this.connection.onClosed = callback;
} }
} }

View File

@ -0,0 +1,10 @@
import { DataReceived, ConnectionClosed } from "./Common"
export interface IConnection {
start(transportName: string): Promise<void>;
send(data: any): Promise<void>;
stop(): void;
onDataReceived: DataReceived;
onClosed: ConnectionClosed;
}

View File

@ -5,14 +5,14 @@ describe('connection', () => {
let connection = new signalR.Connection(ECHOENDPOINT_URL); let connection = new signalR.Connection(ECHOENDPOINT_URL);
let received = ""; let received = "";
connection.dataReceived = data => { connection.onDataReceived = data => {
received += data; received += data;
if (data == message) { if (data == message) {
connection.stop(); connection.stop();
} }
} }
connection.connectionClosed = error => { connection.onClosed = error => {
expect(error).toBeUndefined(); expect(error).toBeUndefined();
done(); done();
} }

View File

@ -5,6 +5,10 @@ describe('hubConnection', () => {
it(`over ${transportName} can invoke server method and receive result`, done => { it(`over ${transportName} can invoke server method and receive result`, done => {
const message = "Hi"; const message = "Hi";
let hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, 'formatType=json&format=text'); let hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, 'formatType=json&format=text');
hubConnection.onClosed = error => {
expect(error).toBe(undefined);
done();
}
hubConnection.start(transportName) hubConnection.start(transportName)
.then(() => { .then(() => {
@ -17,7 +21,6 @@ describe('hubConnection', () => {
}) })
.then(() => { .then(() => {
hubConnection.stop(); hubConnection.stop();
done();
}) })
}) })
.catch(() => { .catch(() => {

View File

@ -102,7 +102,7 @@ connection.on('Send', msg => {
addLine(msg); addLine(msg);
}); });
connection.connectionClosed = e => { connection.onClosed = e => {
if (e) { if (e) {
addLine('Connection closed with error: ' + e, 'red'); addLine('Connection closed with error: ' + e, 'red');
} }

View File

@ -24,7 +24,7 @@
let url = `http://${document.location.host}/chat` let url = `http://${document.location.host}/chat`
let connection = new signalR.Connection(url); let connection = new signalR.Connection(url);
connection.dataReceived = data => { connection.onDataReceived = data => {
let child = document.createElement('li'); let child = document.createElement('li');
child.innerText = data; child.innerText = data;
document.getElementById('messages').appendChild(child); document.getElementById('messages').appendChild(child);