Added IHubProtocol to ts client (#537)
- Mimics the .NET client structure wise - Also adds a JsonHubProtocol implementation
This commit is contained in:
parent
0bbe42a912
commit
50f1d8f9fe
|
|
@ -3,36 +3,10 @@ import { IConnection } from "./IConnection"
|
||||||
import { Connection } from "./Connection"
|
import { Connection } from "./Connection"
|
||||||
import { TransportType } from "./Transports"
|
import { TransportType } from "./Transports"
|
||||||
import { Subject, Observable } from "./Observable"
|
import { Subject, Observable } from "./Observable"
|
||||||
import * as Formatters from "./Formatters";
|
|
||||||
|
|
||||||
const enum MessageType {
|
|
||||||
Invocation = 1,
|
|
||||||
Result,
|
|
||||||
Completion
|
|
||||||
}
|
|
||||||
|
|
||||||
interface HubMessage {
|
|
||||||
readonly type: MessageType;
|
|
||||||
readonly invocationId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface InvocationMessage extends HubMessage {
|
|
||||||
readonly target: string;
|
|
||||||
readonly arguments: Array<any>;
|
|
||||||
readonly nonblocking?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ResultMessage extends HubMessage {
|
|
||||||
readonly item?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CompletionMessage extends HubMessage {
|
|
||||||
readonly error?: string;
|
|
||||||
readonly result?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Connection } from "./Connection"
|
export { Connection } from "./Connection"
|
||||||
export { TransportType } from "./Transports"
|
export { TransportType } from "./Transports"
|
||||||
|
import { IHubProtocol, MessageType, HubMessage, CompletionMessage, ResultMessage, InvocationMessage } from "./IHubProtocol";
|
||||||
|
import { JsonHubProtocol } from "./JsonHubProtocol";
|
||||||
|
|
||||||
export class HubConnection {
|
export class HubConnection {
|
||||||
private connection: IConnection;
|
private connection: IConnection;
|
||||||
|
|
@ -40,6 +14,7 @@ export class HubConnection {
|
||||||
private methods: Map<string, (...args: any[]) => void>;
|
private methods: Map<string, (...args: any[]) => void>;
|
||||||
private id: number;
|
private id: number;
|
||||||
private connectionClosedCallback: ConnectionClosed;
|
private connectionClosedCallback: ConnectionClosed;
|
||||||
|
private protocol: IHubProtocol;
|
||||||
|
|
||||||
static create(url: string, queryString?: string): HubConnection {
|
static create(url: string, queryString?: string): HubConnection {
|
||||||
return new this(new Connection(url, queryString))
|
return new this(new Connection(url, queryString))
|
||||||
|
|
@ -59,22 +34,16 @@ export class HubConnection {
|
||||||
this.callbacks = new Map<string, (invocationEvent: CompletionMessage | ResultMessage) => void>();
|
this.callbacks = new Map<string, (invocationEvent: CompletionMessage | ResultMessage) => void>();
|
||||||
this.methods = new Map<string, (...args: any[]) => void>();
|
this.methods = new Map<string, (...args: any[]) => void>();
|
||||||
this.id = 0;
|
this.id = 0;
|
||||||
|
this.protocol = new JsonHubProtocol();
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDataReceived(data: any) {
|
private onDataReceived(data: any) {
|
||||||
// TODO: separate JSON parsing
|
|
||||||
// Can happen if a poll request was cancelled
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the messages
|
// Parse the messages
|
||||||
let messages = Formatters.TextMessageFormat.parse(data);
|
let messages = this.protocol.parseMessages(data);
|
||||||
|
|
||||||
for (var i = 0; i < messages.length; ++i) {
|
for (var i = 0; i < messages.length; ++i) {
|
||||||
console.log(`Received message: ${messages[i]}`);
|
var message = messages[i];
|
||||||
|
|
||||||
var message = JSON.parse(messages[i]);
|
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case MessageType.Invocation:
|
case MessageType.Invocation:
|
||||||
this.InvokeClientMethod(<InvocationMessage>message);
|
this.InvokeClientMethod(<InvocationMessage>message);
|
||||||
|
|
@ -159,8 +128,7 @@ export class HubConnection {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: separate conversion to enable different data formats
|
let message = this.protocol.writeMessage(invocationDescriptor);
|
||||||
let message = this.framePayload(invocationDescriptor);
|
|
||||||
|
|
||||||
this.connection.send(message)
|
this.connection.send(message)
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
|
|
@ -190,8 +158,7 @@ export class HubConnection {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: separate conversion to enable different data formats
|
let message = this.protocol.writeMessage(invocationDescriptor);
|
||||||
let message = this.framePayload(invocationDescriptor);
|
|
||||||
|
|
||||||
this.connection.send(message)
|
this.connection.send(message)
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
|
|
@ -211,11 +178,6 @@ export class HubConnection {
|
||||||
this.connectionClosedCallback = callback;
|
this.connectionClosedCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
private framePayload(invocationDescriptor: InvocationMessage): string {
|
|
||||||
let data = JSON.stringify(invocationDescriptor);
|
|
||||||
return Formatters.TextMessageFormat.write(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private createInvocation(methodName: string, args: any[]): InvocationMessage {
|
private createInvocation(methodName: string, args: any[]): InvocationMessage {
|
||||||
let id = this.id;
|
let id = this.id;
|
||||||
this.id++;
|
this.id++;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
export const enum MessageType {
|
||||||
|
Invocation = 1,
|
||||||
|
Result,
|
||||||
|
Completion
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HubMessage {
|
||||||
|
readonly type: MessageType;
|
||||||
|
readonly invocationId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InvocationMessage extends HubMessage {
|
||||||
|
readonly target: string;
|
||||||
|
readonly arguments: Array<any>;
|
||||||
|
readonly nonblocking?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResultMessage extends HubMessage {
|
||||||
|
readonly item?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompletionMessage extends HubMessage {
|
||||||
|
readonly error?: string;
|
||||||
|
readonly result?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IHubProtocol {
|
||||||
|
parseMessages(input: string): HubMessage[];
|
||||||
|
writeMessage(message: HubMessage): string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { TextMessageFormat } from "./Formatters";
|
||||||
|
import { IHubProtocol, HubMessage } from "./IHubProtocol";
|
||||||
|
|
||||||
|
export class JsonHubProtocol implements IHubProtocol {
|
||||||
|
parseMessages(input: string): HubMessage[] {
|
||||||
|
if (!input) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the messages
|
||||||
|
let messages = TextMessageFormat.parse(input);
|
||||||
|
let hubMessages = [];
|
||||||
|
for (var i = 0; i < messages.length; ++i) {
|
||||||
|
hubMessages.push(JSON.parse(messages[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return hubMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeMessage(message: HubMessage): string {
|
||||||
|
return TextMessageFormat.write(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Inputs Include="*.ts;" />
|
<Inputs Include="*.ts;" />
|
||||||
<Inputs Remove="Observable.ts" />
|
|
||||||
<Outputs Include="@(Inputs -> '$(SignalRClientDistFolder)src\%(FileName).d.ts')" />
|
<Outputs Include="@(Inputs -> '$(SignalRClientDistFolder)src\%(FileName).d.ts')" />
|
||||||
<Outputs Include="@(Inputs -> '$(SignalRClientDistFolder)src\%(FileName).js')" />
|
<Outputs Include="@(Inputs -> '$(SignalRClientDistFolder)src\%(FileName).js')" />
|
||||||
<Outputs Include="$(SignalRClientDistFolder)browser\signalr-client.js" />
|
<Outputs Include="$(SignalRClientDistFolder)browser\signalr-client.js" />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue