Merge branch 'rel/1.0.0-alpha1' into dev
This commit is contained in:
commit
0557319870
|
|
@ -9,6 +9,10 @@ import { ITransport, TransportType, TransferMode } from "../Microsoft.AspNetCore
|
|||
import { eachTransport } from "./Common";
|
||||
|
||||
describe("Connection", () => {
|
||||
it("cannot be created with relative url if document object is not present", () => {
|
||||
expect(() => new HttpConnection("/test"))
|
||||
.toThrow(new Error("Cannot resolve '/test'."));
|
||||
});
|
||||
|
||||
it("starting connection fails if getting id fails", async (done) => {
|
||||
let options: IHttpConnectionOptions = {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ export namespace TextMessageFormat {
|
|||
|
||||
export namespace BinaryMessageFormat {
|
||||
export function write(output: Uint8Array): ArrayBuffer {
|
||||
let size = output.byteLength;
|
||||
// .byteLength does is undefined in IE10
|
||||
let size = output.byteLength || output.length;
|
||||
let buffer = new Uint8Array(size + 8);
|
||||
|
||||
// javascript bitwise operators only support 32-bit integers
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@ export class HttpConnection implements IConnection {
|
|||
readonly features: any = {};
|
||||
|
||||
constructor(url: string, options: IHttpConnectionOptions = {}) {
|
||||
this.url = url;
|
||||
this.logger = LoggerFactory.createLogger(options.logging);
|
||||
this.url = this.resolveUrl(url);
|
||||
options = options || {};
|
||||
this.httpClient = options.httpClient || new HttpClient();
|
||||
this.logger = LoggerFactory.createLogger(options.logging);
|
||||
this.connectionState = ConnectionState.Initial;
|
||||
this.options = options;
|
||||
}
|
||||
|
|
@ -156,6 +156,28 @@ export class HttpConnection implements IConnection {
|
|||
}
|
||||
}
|
||||
|
||||
private resolveUrl(url: string) : string {
|
||||
// startsWith is not supported in IE
|
||||
if (url.lastIndexOf("https://", 0) === 0 || url.lastIndexOf("http://", 0) === 0) {
|
||||
return url;
|
||||
}
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
throw new Error(`Cannot resolve '${url}'.`);
|
||||
}
|
||||
|
||||
let parser = window.document.createElement("a");
|
||||
parser.href = url;
|
||||
|
||||
let baseUrl = (!parser.protocol || parser.protocol === ":")
|
||||
? `${window.document.location.protocol}//${(parser.host || window.document.location.host)}`
|
||||
: `${parser.protocol}//${parser.host}`;
|
||||
|
||||
let normalizedUrl = baseUrl + url;
|
||||
this.logger.log(LogLevel.Information, `Normalizing '${url}' to '${normalizedUrl}'`);
|
||||
return normalizedUrl;
|
||||
}
|
||||
|
||||
onDataReceived: DataReceived;
|
||||
onClosed: ConnectionClosed;
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import { ConnectionClosed } from "./Common"
|
||||
import { IConnection } from "./IConnection"
|
||||
import { HttpConnection} from "./HttpConnection"
|
||||
import { TransportType, TransferMode } from "./Transports"
|
||||
import { Subject, Observable } from "./Observable"
|
||||
import { IHubProtocol, ProtocolType, MessageType, HubMessage, CompletionMessage, ResultMessage, InvocationMessage, NegotiationMessage } from "./IHubProtocol";
|
||||
|
|
@ -28,9 +29,15 @@ export class HubConnection {
|
|||
private id: number;
|
||||
private connectionClosedCallback: ConnectionClosed;
|
||||
|
||||
constructor(connection: IConnection, options: IHubConnectionOptions = {}) {
|
||||
this.connection = connection;
|
||||
constructor(urlOrConnection: string | IConnection, options: IHubConnectionOptions = {}) {
|
||||
options = options || {};
|
||||
if (typeof urlOrConnection === "string") {
|
||||
this.connection = new HttpConnection(urlOrConnection, options);
|
||||
}
|
||||
else {
|
||||
this.connection = urlOrConnection;
|
||||
}
|
||||
|
||||
this.logger = LoggerFactory.createLogger(options.logging);
|
||||
|
||||
this.protocol = options.protocol || new JsonHubProtocol();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
// 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.
|
||||
|
||||
import { IHttpConnectionOptions } from "./IHttpConnectionOptions"
|
||||
import { IHubProtocol } from "./IHubProtocol"
|
||||
import { ILogger, LogLevel } from "./ILogger"
|
||||
|
||||
export interface IHubConnectionOptions {
|
||||
export interface IHubConnectionOptions extends IHttpConnectionOptions {
|
||||
protocol?: IHubProtocol;
|
||||
logging?: ILogger | LogLevel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,12 +247,12 @@ export class LongPollingTransport implements ITransport {
|
|||
}
|
||||
|
||||
this.pollXhr = pollXhr;
|
||||
this.pollXhr.open("GET", url, true);
|
||||
|
||||
this.pollXhr.open("GET", `${url}&_=${Date.now()}`, true);
|
||||
if (transferMode === TransferMode.Binary) {
|
||||
this.pollXhr.responseType = "arraybuffer";
|
||||
}
|
||||
// IE caches xhr requests
|
||||
this.pollXhr.setRequestHeader("Cache-Control", "no-cache");
|
||||
|
||||
// TODO: consider making timeout configurable
|
||||
this.pollXhr.timeout = 120000;
|
||||
this.pollXhr.send();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@
|
|||
var ECHOENDPOINT_URL = "http://" + document.location.host + "/echo";
|
||||
|
||||
function getTransportTypes() {
|
||||
var transportTypes = [signalR.TransportType.WebSockets];
|
||||
var transportTypes = [];
|
||||
if (typeof WebSocket !== "undefined") {
|
||||
transportTypes.push(signalR.TransportType.WebSockets);
|
||||
}
|
||||
if (typeof EventSource !== "undefined") {
|
||||
transportTypes.push(signalR.TransportType.ServerSentEvents);
|
||||
}
|
||||
|
|
@ -22,7 +25,12 @@ function eachTransport(action) {
|
|||
}
|
||||
|
||||
function eachTransportAndProtocol(action) {
|
||||
var protocols = [new signalR.JsonHubProtocol(), new signalRMsgPack.MessagePackHubProtocol()];
|
||||
var protocols = [new signalR.JsonHubProtocol()];
|
||||
// IE9 does not support XmlHttpRequest advanced features so disable for now
|
||||
// This can be enabled if we fix: https://github.com/aspnet/SignalR/issues/742
|
||||
if (typeof new XMLHttpRequest().responseType === "string") {
|
||||
protocols.push(new signalRMsgPack.MessagePackHubProtocol());
|
||||
}
|
||||
getTransportTypes().forEach(function (t) {
|
||||
return protocols.forEach(function (p) {
|
||||
return action(t, p);
|
||||
|
|
|
|||
|
|
@ -4,30 +4,32 @@
|
|||
"use strict";
|
||||
|
||||
describe('connection', function () {
|
||||
it("can connect to the server without specifying transport explicitly", function (done) {
|
||||
var message = "Hello World!";
|
||||
var connection = new signalR.HttpConnection(ECHOENDPOINT_URL);
|
||||
if (typeof WebSocket !== 'undefined') {
|
||||
it("can connect to the server without specifying transport explicitly", function (done) {
|
||||
var message = "Hello World!";
|
||||
var connection = new signalR.HttpConnection(ECHOENDPOINT_URL);
|
||||
|
||||
var received = "";
|
||||
connection.onDataReceived = function (data) {
|
||||
received += data;
|
||||
if (data == message) {
|
||||
connection.stop();
|
||||
}
|
||||
};
|
||||
var received = "";
|
||||
connection.onDataReceived = function (data) {
|
||||
received += data;
|
||||
if (data == message) {
|
||||
connection.stop();
|
||||
}
|
||||
};
|
||||
|
||||
connection.onClosed = function (error) {
|
||||
expect(error).toBeUndefined();
|
||||
done();
|
||||
};
|
||||
connection.onClosed = function (error) {
|
||||
expect(error).toBeUndefined();
|
||||
done();
|
||||
};
|
||||
|
||||
connection.start().then(function () {
|
||||
connection.send(message);
|
||||
}).catch(function (e) {
|
||||
fail();
|
||||
done();
|
||||
connection.start().then(function () {
|
||||
connection.send(message);
|
||||
}).catch(function (e) {
|
||||
fail();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
eachTransport(function (transportType) {
|
||||
it("over " + signalR.TransportType[transportType] + " can send and receive messages", function (done) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var TESTHUBENDPOINT_URL = 'http://' + document.location.host + '/testhub';
|
||||
var TESTHUBENDPOINT_URL = '/testhub';
|
||||
|
||||
describe('hubConnection', function () {
|
||||
eachTransportAndProtocol(function (transportType, protocol) {
|
||||
|
|
@ -17,7 +17,7 @@ describe('hubConnection', function () {
|
|||
protocol: protocol,
|
||||
logging: signalR.LogLevel.Trace
|
||||
};
|
||||
var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, options), options);
|
||||
var hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, options);
|
||||
hubConnection.onClosed = function (error) {
|
||||
expect(error).toBe(undefined);
|
||||
done();
|
||||
|
|
@ -44,7 +44,7 @@ describe('hubConnection', function () {
|
|||
protocol: protocol,
|
||||
logging: signalR.LogLevel.Trace
|
||||
};
|
||||
var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, options), options);
|
||||
var hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, options);
|
||||
|
||||
hubConnection.onClosed = function (error) {
|
||||
expect(error).toBe(undefined);
|
||||
|
|
@ -79,7 +79,7 @@ describe('hubConnection', function () {
|
|||
protocol: protocol,
|
||||
logging: signalR.LogLevel.Trace
|
||||
};
|
||||
var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, options), options);
|
||||
var hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, options);
|
||||
|
||||
hubConnection.start().then(function () {
|
||||
hubConnection.invoke('ThrowException', errorMessage).then(function () {
|
||||
|
|
@ -105,7 +105,7 @@ describe('hubConnection', function () {
|
|||
protocol: protocol,
|
||||
logging: signalR.LogLevel.Trace
|
||||
};
|
||||
var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, options), options);
|
||||
var hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, options);
|
||||
|
||||
hubConnection.start().then(function () {
|
||||
hubConnection.stream('ThrowException', errorMessage).subscribe({
|
||||
|
|
@ -132,7 +132,7 @@ describe('hubConnection', function () {
|
|||
protocol: protocol,
|
||||
logging: signalR.LogLevel.Trace
|
||||
};
|
||||
var hubConnection = new signalR.HubConnection(new signalR.HttpConnection(TESTHUBENDPOINT_URL, options), options);
|
||||
var hubConnection = new signalR.HubConnection(TESTHUBENDPOINT_URL, options);
|
||||
|
||||
var message = "你好 SignalR!";
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ describe('hubConnection', function () {
|
|||
protocol: protocol,
|
||||
logging: signalR.LogLevel.Trace
|
||||
};
|
||||
var hubConnection = new signalR.HubConnection(new signalR.HttpConnection('http://' + document.location.host + '/uncreatable', options), options);
|
||||
var hubConnection = new signalR.HubConnection('http://' + document.location.host + '/uncreatable', options);
|
||||
|
||||
hubConnection.onClosed = function (error) {
|
||||
expect(error.message).toMatch(errorRegex[signalR.TransportType[transportType]]);
|
||||
|
|
|
|||
|
|
@ -3,33 +3,35 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
describe('WebSockets', function () {
|
||||
it('can be used to connect to SignalR', function (done) {
|
||||
var message = "message";
|
||||
if (typeof WebSocket !== 'undefined') {
|
||||
describe('WebSockets', function () {
|
||||
it('can be used to connect to SignalR', function (done) {
|
||||
var message = "message";
|
||||
|
||||
var webSocket = new WebSocket(ECHOENDPOINT_URL.replace(/^http/, "ws"));
|
||||
var webSocket = new WebSocket(ECHOENDPOINT_URL.replace(/^http/, "ws"));
|
||||
|
||||
webSocket.onopen = function () {
|
||||
webSocket.send(message);
|
||||
};
|
||||
webSocket.onopen = function () {
|
||||
webSocket.send(message);
|
||||
};
|
||||
|
||||
var received = "";
|
||||
webSocket.onmessage = function (event) {
|
||||
received += event.data;
|
||||
if (received === message) {
|
||||
webSocket.close();
|
||||
}
|
||||
};
|
||||
var received = "";
|
||||
webSocket.onmessage = function (event) {
|
||||
received += event.data;
|
||||
if (received === message) {
|
||||
webSocket.close();
|
||||
}
|
||||
};
|
||||
|
||||
webSocket.onclose = function (event) {
|
||||
if (!event.wasClean) {
|
||||
fail("connection closed with unexpected status code: " + event.code + " " + event.reason);
|
||||
}
|
||||
webSocket.onclose = function (event) {
|
||||
if (!event.wasClean) {
|
||||
fail("connection closed with unexpected status code: " + event.code + " " + event.reason);
|
||||
}
|
||||
|
||||
// Jasmine doesn't like tests without expectations
|
||||
expect(event.wasClean).toBe(true);
|
||||
// Jasmine doesn't like tests without expectations
|
||||
expect(event.wasClean).toBe(true);
|
||||
|
||||
done();
|
||||
};
|
||||
done();
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue