Skip to content

Commit 7932622

Browse files
authored
Add ability to change url in TS client (dotnet#11102)
1 parent 14e7aca commit 7932622

File tree

7 files changed

+111
-3
lines changed

7 files changed

+111
-3
lines changed

src/Components/Browser.JS/dist/Release/blazor.server.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,36 @@ describe("hubConnection", () => {
750750
}
751751
});
752752
});
753+
754+
it("can change url in reconnecting state", async (done) => {
755+
try {
756+
const reconnectingPromise = new PromiseSource();
757+
const hubConnection = getConnectionBuilder(transportType)
758+
.withAutomaticReconnect()
759+
.build();
760+
761+
hubConnection.onreconnecting(() => {
762+
hubConnection.baseUrl = "http://example123.com";
763+
reconnectingPromise.resolve();
764+
});
765+
766+
await hubConnection.start();
767+
768+
// Induce reconnect
769+
(hubConnection as any).serverTimeout();
770+
771+
await reconnectingPromise;
772+
773+
expect(hubConnection.baseUrl).toBe("http://example123.com");
774+
775+
await hubConnection.stop();
776+
777+
done();
778+
} catch (err) {
779+
fail(err);
780+
done();
781+
}
782+
});
753783
});
754784

755785
it("can reconnect after negotiate redirect", async (done) => {

src/SignalR/clients/ts/signalr/src/HttpConnection.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ export class HttpConnection implements IConnection {
5353
// connectionStarted is tracked independently from connectionState, so we can check if the
5454
// connection ever did successfully transition from connecting to connected before disconnecting.
5555
private connectionStarted: boolean;
56-
private readonly baseUrl: string;
5756
private readonly httpClient: HttpClient;
5857
private readonly logger: ILogger;
5958
private readonly options: IHttpConnectionOptions;
@@ -66,6 +65,7 @@ export class HttpConnection implements IConnection {
6665
private sendQueue?: TransportSendQueue;
6766

6867
public readonly features: any = {};
68+
public baseUrl: string;
6969
public connectionId?: string;
7070
public onreceive: ((data: string | ArrayBuffer) => void) | null;
7171
public onclose: ((e?: Error) => void) | null;

src/SignalR/clients/ts/signalr/src/HubConnection.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,28 @@ export class HubConnection {
127127
return this.connection ? (this.connection.connectionId || null) : null;
128128
}
129129

130+
/** Indicates the url of the {@link HubConnection} to the server. */
131+
get baseUrl(): string {
132+
return this.connection.baseUrl || "";
133+
}
134+
135+
/**
136+
* Sets a new url for the HubConnection. Note that the url can only be changed when the connection is in either the Disconnected or
137+
* Reconnecting states.
138+
* @param {string} url The url to connect to.
139+
*/
140+
set baseUrl(url: string) {
141+
if (this.connectionState !== HubConnectionState.Disconnected && this.connectionState !== HubConnectionState.Reconnecting) {
142+
throw new Error("The HubConnection must be in the Disconnected or Reconnecting state to change the url.");
143+
}
144+
145+
if (!url) {
146+
throw new Error("The HubConnection url must be a valid url.");
147+
}
148+
149+
this.connection.baseUrl = url;
150+
}
151+
130152
/** Starts the connection.
131153
*
132154
* @returns {Promise<void>} A Promise that resolves when the connection has been successfully established, or rejects with an error.

src/SignalR/clients/ts/signalr/src/IConnection.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export interface IConnection {
88
readonly features: any;
99
readonly connectionId?: string;
1010

11+
baseUrl: string;
12+
1113
start(transferFormat: TransferFormat): Promise<void>;
1214
send(data: string | ArrayBuffer): Promise<void>;
1315
stop(error?: Error): Promise<void>;

src/SignalR/clients/ts/signalr/tests/HubConnection.test.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,58 @@ describe("HubConnection", () => {
4141
});
4242
});
4343

44+
it("can change url", async () => {
45+
await VerifyLogger.run(async (logger) => {
46+
const connection = new TestConnection();
47+
const hubConnection = createHubConnection(connection, logger);
48+
try {
49+
await hubConnection.start();
50+
await hubConnection.stop();
51+
hubConnection.baseUrl = "http://newurl.com";
52+
expect(hubConnection.baseUrl).toBe("http://newurl.com");
53+
} finally {
54+
await hubConnection.stop();
55+
}
56+
});
57+
});
58+
59+
it("can change url in onclose", async () => {
60+
await VerifyLogger.run(async (logger) => {
61+
const connection = new TestConnection();
62+
const hubConnection = createHubConnection(connection, logger);
63+
try {
64+
await hubConnection.start();
65+
66+
expect(hubConnection.baseUrl).toBe("http://example.com");
67+
hubConnection.onclose(() => {
68+
hubConnection.baseUrl = "http://newurl.com";
69+
});
70+
71+
await hubConnection.stop();
72+
expect(hubConnection.baseUrl).toBe("http://newurl.com");
73+
} finally {
74+
await hubConnection.stop();
75+
}
76+
});
77+
});
78+
79+
it("changing url while active throws", async () => {
80+
await VerifyLogger.run(async (logger) => {
81+
const connection = new TestConnection();
82+
const hubConnection = createHubConnection(connection, logger);
83+
try {
84+
await hubConnection.start();
85+
86+
expect(() => {
87+
hubConnection.baseUrl = "http://newurl.com";
88+
}).toThrow("The HubConnection must be in the Disconnected or Reconnecting state to change the url.");
89+
90+
} finally {
91+
await hubConnection.stop();
92+
}
93+
});
94+
});
95+
4496
it("state connected", async () => {
4597
await VerifyLogger.run(async (logger) => {
4698
const connection = new TestConnection();
@@ -1076,7 +1128,7 @@ describe("HubConnection", () => {
10761128
hubConnection.stream("testMethod").subscribe(NullSubscriber.instance);
10771129

10781130
// Send completion to trigger observer.complete()
1079-
// Expectation is connection.receive will not to throw
1131+
// Expectation is connection.receive will not throw
10801132
connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId });
10811133
} finally {
10821134
await hubConnection.stop();

src/SignalR/clients/ts/signalr/tests/TestConnection.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { IConnection } from "../src/IConnection";
55
import { TextMessageFormat } from "../src/TextMessageFormat";
66

77
export class TestConnection implements IConnection {
8+
public baseUrl: string;
89
public readonly features: any = {};
910
public connectionId?: string;
1011

@@ -22,6 +23,7 @@ export class TestConnection implements IConnection {
2223
this.sentData = [];
2324
this.lastInvocationId = null;
2425
this.autoHandshake = autoHandshake;
26+
this.baseUrl = "http://example.com";
2527
}
2628

2729
public start(): Promise<void> {

0 commit comments

Comments
 (0)