Hub connection tests
This commit is contained in:
parent
d3e625c985
commit
46cf13b2fc
|
|
@ -35,6 +35,10 @@ export class HubConnection {
|
|||
|
||||
private dataReceived(data: any) {
|
||||
//TODO: separate JSON parsing
|
||||
// Can happen if a poll request was cancelled
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
var descriptor = JSON.parse(data);
|
||||
if (descriptor.Method === undefined) {
|
||||
let invocationResult: InvocationResultDescriptor = descriptor;
|
||||
|
|
@ -62,7 +66,7 @@ export class HubConnection {
|
|||
return this.connection.stop();
|
||||
}
|
||||
|
||||
invoke(methodName: string, ...args: any[]): Promise<void> {
|
||||
invoke(methodName: string, ...args: any[]): Promise<any> {
|
||||
|
||||
let id = this.id;
|
||||
this.id++;
|
||||
|
|
@ -76,7 +80,7 @@ export class HubConnection {
|
|||
let p = new Promise<any>((resolve, reject) => {
|
||||
this.callbacks[id] = (invocationResult: InvocationResultDescriptor) => {
|
||||
if (invocationResult.Error != null) {
|
||||
reject(invocationResult.Error);
|
||||
reject(new Error(invocationResult.Error));
|
||||
}
|
||||
else {
|
||||
resolve(invocationResult.Result);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export class WebSocketTransport implements ITransport {
|
|||
private webSocket: WebSocket;
|
||||
|
||||
connect(url: string, queryString: string = ""): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
url = url.replace(/^http/, "ws");
|
||||
let connectUrl = url + "/ws?" + queryString;
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ export class WebSocketTransport implements ITransport {
|
|||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return Promise.reject("WebSocket is not in OPEN state");
|
||||
return Promise.reject("WebSocket is not in the OPEN state");
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
|
|
@ -81,7 +81,7 @@ export class ServerSentEventsTransport implements ITransport {
|
|||
this.url = url;
|
||||
let tmp = `${this.url}/sse?${this.queryString}`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
let eventSource = new EventSource(`${this.url}/sse?${this.queryString}`);
|
||||
|
||||
try {
|
||||
|
|
@ -131,15 +131,21 @@ export class LongPollingTransport implements ITransport {
|
|||
private url: string;
|
||||
private queryString: string;
|
||||
private pollXhr: XMLHttpRequest;
|
||||
private shouldPoll: boolean;
|
||||
|
||||
connect(url: string, queryString: string): Promise<void> {
|
||||
this.url = url;
|
||||
this.queryString = queryString;
|
||||
this.shouldPoll = true;
|
||||
this.poll(url + "/poll?" + this.queryString)
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
private poll(url: string): void {
|
||||
if (!this.shouldPoll) {
|
||||
return;
|
||||
}
|
||||
|
||||
let thisLongPollingTransport = this;
|
||||
let pollXhr = new XMLHttpRequest();
|
||||
|
||||
|
|
@ -188,6 +194,7 @@ export class LongPollingTransport implements ITransport {
|
|||
}
|
||||
|
||||
stop(): void {
|
||||
this.shouldPoll = false;
|
||||
if (this.pollXhr) {
|
||||
this.pollXhr.abort();
|
||||
this.pollXhr = null;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
using System;
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO.Pipelines;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Sockets;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
using System;
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -25,6 +28,10 @@ namespace Microsoft.AspNetCore.SignalR.Test.Server
|
|||
|
||||
app.UseStaticFiles();
|
||||
app.UseSockets(options => options.MapEndpoint<EchoEndPoint>("/echo"));
|
||||
app.UseSignalR(routes =>
|
||||
{
|
||||
routes.MapHub<TestHub>("/testhub");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.SignalR.Test.Server
|
||||
{
|
||||
public class TestHub : Hub
|
||||
{
|
||||
public string Echo(string message)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
public void ThrowException(string message)
|
||||
{
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
public Task InvokeWithString(string message)
|
||||
{
|
||||
return Clients.Client(Context.Connection.ConnectionId).InvokeAsync("Message", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
<script src="js/common.js"></script>
|
||||
<script src="js/webSocketTests.js"></script>
|
||||
<script src="js/connectionTests.js"></script>
|
||||
<script src="js/hubConnectionTests.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -3,4 +3,8 @@ const ECHOENDPOINT_URL = `http://${document.location.host}/echo`;
|
|||
function eachTransport(action) {
|
||||
let transportNames = ["webSockets", "serverSentEvents", "longPolling"];
|
||||
transportNames.forEach(t => action(t));
|
||||
}
|
||||
|
||||
function fail() {
|
||||
it.expect(true).toBe(false);
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
describe('connection', () => {
|
||||
eachTransport(transportName => {
|
||||
it(`over ${transportName} can send and receive messages`, done => {
|
||||
|
|
@ -23,7 +22,7 @@ describe('connection', () => {
|
|||
connection.send(message);
|
||||
})
|
||||
.catch(e => {
|
||||
expect(true).toBe(false);
|
||||
fail();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
const TESTHUBENDPOINT_URL = `http://${document.location.host}/testhub`;
|
||||
|
||||
describe('hubConnection', () => {
|
||||
eachTransport(transportName => {
|
||||
it(`over ${transportName} can invoke server method and receive result`, done => {
|
||||
const message = "Hi";
|
||||
let hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, 'formatType=json&format=text');
|
||||
|
||||
hubConnection.start(transportName)
|
||||
.then(() => {
|
||||
hubConnection.invoke('Echo', message)
|
||||
.then(result => {
|
||||
expect(result).toBe(message);
|
||||
})
|
||||
.catch(() => {
|
||||
fail();
|
||||
})
|
||||
.then(() => {
|
||||
hubConnection.stop();
|
||||
done();
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
fail();
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it(`over ${transportName} rethrows an exception from the server`, done => {
|
||||
const errorMessage = "An error occurred.";
|
||||
let hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, 'formatType=json&format=text');
|
||||
|
||||
hubConnection.start(transportName)
|
||||
.then(() => {
|
||||
hubConnection.invoke('ThrowException', errorMessage)
|
||||
.then(() => {
|
||||
// exception expected but none thrown
|
||||
fail();
|
||||
})
|
||||
.catch(e => {
|
||||
expect(e.message).toBe(errorMessage);
|
||||
})
|
||||
.then(() => {
|
||||
hubConnection.stop();
|
||||
done();
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
fail();
|
||||
done();
|
||||
})
|
||||
});
|
||||
|
||||
it(`over ${transportName} can receive server calls`, done => {
|
||||
let client = new signalR.HubConnection(TESTHUBENDPOINT_URL, 'formatType=json&format=text');
|
||||
const message = "Hello SignalR";
|
||||
|
||||
client.on("Message", msg => {
|
||||
expect(msg).toBe(message);
|
||||
client.stop();
|
||||
done();
|
||||
});
|
||||
|
||||
client.start(transportName)
|
||||
.then(() => {
|
||||
client.invoke('InvokeWithString', message)
|
||||
.catch(e => {
|
||||
fail();
|
||||
client.stop();
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
fail();
|
||||
done();
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
};
|
||||
|
||||
webSocket.onerror = event => {
|
||||
expect(true).toBe(false);
|
||||
fail();
|
||||
done();
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue