Skip to content

Commit

Permalink
feat: close events
Browse files Browse the repository at this point in the history
  • Loading branch information
dimitrovs committed Aug 22, 2021
1 parent f0c83ac commit 5cbc4cd
Show file tree
Hide file tree
Showing 15 changed files with 447 additions and 226 deletions.
Binary file modified .DS_Store
Binary file not shown.
15 changes: 12 additions & 3 deletions example/host.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@
document.getElementById("hostId").value = host.hostId;
alert("Host ready!");
});
host.on("error", console.error);
host.on("error", function (error) {
if (error instanceof uhst.RelayError) {
alert("Disconnected.");
} else {
console.error(error);
}
});
host.on("diagnostic", console.log);
host.on("connection", function connection(ws) {
ws.on("diagnostic", console.log);
ws.on("message", function incoming(message) {
console.log("Host received: %s from %s", message, ws.remoteId);
host.broadcast("Host received: "+ message);
host.broadcast("Host received: " + message);
});
ws.on("open", function ready() {
console.log("Client %s connected", ws.remoteId);
ws.send("something");
});
ws.on("close", function disconnected() {
console.log("Client %s disconnected.", ws.remoteId);
});
});
</script>
Host ID: <input id="hostId" disabled/>
Host ID: <input id="hostId" disabled />
5 changes: 4 additions & 1 deletion example/join.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
ws.on("message", function incoming(message) {
console.log("Client received: %s", message);
});
ws.on("close", function close() {
console.log("Connection to host %s dropped.", ws.remoteId);
});
}

</script>
Host ID: <input id="hostId"/>
Host ID: <input id="hostId" />
<button onclick="join()">Join</button>
13 changes: 11 additions & 2 deletions lib/ApiClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
MessageHandler,
MessageStream,
RelayEventHandler,
UhstRelayClient,
} from './contracts/UhstRelayClient';
import { HostConfiguration, ClientConfiguration } from './models';
Expand Down Expand Up @@ -71,9 +72,17 @@ export class ApiClient implements UhstRelayClient {

subscribeToMessages(
token: string,
handler: MessageHandler,
messageHandler: MessageHandler,
relayErrorHandler: Function,
relayEventHandler: RelayEventHandler,
receiveUrl?: string
): Promise<MessageStream> {
return this.relayClient.subscribeToMessages(token, handler, receiveUrl);
return this.relayClient.subscribeToMessages(
token,
messageHandler,
relayErrorHandler,
relayEventHandler,
receiveUrl
);
}
}
62 changes: 40 additions & 22 deletions lib/NetworkClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,69 @@ const REQUEST_OPTIONS = {
method: 'POST',
};

const getRequestOptions = (body: any): any => {
if (body) {
return {
...REQUEST_OPTIONS,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
};
} else {
return REQUEST_OPTIONS;
}
};

export class NetworkClient {
async post(
url: string,
queryParams?: string[],
body?: any,
timeout?: number
): Promise<any> {
if (queryParams && queryParams.length > 0) {
url = `${url}?${queryParams.join('&')}`;
}
let response: Response;
try {
if (queryParams && queryParams.length > 0) {
url = `${url}?${queryParams.join('&')}`;
}
const response = timeout
? await this.fetchWithTimeout(url, { ...REQUEST_OPTIONS, timeout })
: await fetch(url, REQUEST_OPTIONS);
if (response.status == 200) {
return response.json();
} else {
throw new NetworkError(response.status, `${response.statusText}`);
}
response = timeout
? await this.fetchWithTimeout(url, {
...getRequestOptions(body),
timeout,
})
: await fetch(url, getRequestOptions(body));
} catch (error) {
console.log(error);
throw new NetworkUnreachable(error);
}
if (response.status == 200) {
return response.json();
} else {
throw new NetworkError(response.status, `${response.statusText}`);
}
}

async get(
url: string,
queryParams?: string[],
timeout?: number
): Promise<any> {
if (queryParams && queryParams.length > 0) {
url = `${url}?${queryParams.join('&')}`;
}
let response: Response;
try {
if (queryParams && queryParams.length > 0) {
url = `${url}?${queryParams.join('&')}`;
}
const response = timeout
response = timeout
? await this.fetchWithTimeout(url, { timeout })
: await fetch(url);
if (response.status == 200) {
return response.json();
} else {
throw new NetworkError(response.status, `${response.statusText}`);
}
} catch (error) {
console.log(error);
throw new NetworkUnreachable(error);
}
if (response.status == 200) {
return response.json();
} else {
throw new NetworkError(response.status, `${response.statusText}`);
}
}

async fetchWithTimeout(resource, options): Promise<any> {
Expand Down
83 changes: 48 additions & 35 deletions lib/RelayClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import {
UhstRelayClient,
MessageHandler,
MessageStream,
RelayEventHandler,
} from './contracts/UhstRelayClient';
import { ClientConfiguration, HostConfiguration, Message } from './models';
import { ClientConfiguration, HostConfiguration, Message, RelayEvent } from './models';
import {
InvalidToken,
InvalidHostId,
Expand All @@ -15,13 +16,6 @@ import {
} from './UhstErrors';
import { NetworkClient } from './NetworkClient';

const REQUEST_OPTIONS = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
};

export class RelayClient implements UhstRelayClient {
networkClient: NetworkClient;
constructor(private relayUrl: string, networkClient?: NetworkClient) {
Expand All @@ -30,10 +24,11 @@ export class RelayClient implements UhstRelayClient {

async initHost(hostId?: string): Promise<HostConfiguration> {
try {
return this.networkClient.post(
const hostConfig = await this.networkClient.post(
this.relayUrl,
hostId ? ['action=host', `hostId=${hostId}`] : ['action=host']
);
return hostConfig;
} catch (error) {
if (error instanceof NetworkError) {
if (error.responseCode == 400) {
Expand All @@ -42,18 +37,18 @@ export class RelayClient implements UhstRelayClient {
throw new RelayError(error.message);
}
} else {
console.log(error);
throw new RelayUnreachable(error);
}
}
}

async initClient(hostId: string): Promise<ClientConfiguration> {
try {
return this.networkClient.post(this.relayUrl, [
const clientConfig = await this.networkClient.post(this.relayUrl, [
'action=join',
`hostId=${hostId}`,
]);
return clientConfig;
} catch (error) {
if (error instanceof NetworkError) {
if (error.responseCode == 400) {
Expand All @@ -62,7 +57,6 @@ export class RelayClient implements UhstRelayClient {
throw new RelayError(error.message);
}
} else {
console.log(error);
throw new RelayUnreachable(error);
}
}
Expand All @@ -72,47 +66,66 @@ export class RelayClient implements UhstRelayClient {
token: string,
message: any,
sendUrl?: string
): Promise<void> {
): Promise<any> {
const url = sendUrl ?? this.relayUrl;
let response: Response;
try {
response = await fetch(`${url}?token=${token}`, {
...REQUEST_OPTIONS,
body: JSON.stringify(message),
});
const response = await this.networkClient.post(
url,
[`token=${token}`],
message
);
return response;
} catch (error) {
console.log(error);
throw new RelayUnreachable(error);
}
if (response.status == 200) {
return;
} else if (response.status == 400) {
throw new InvalidClientOrHostId(response.statusText);
} else if (response.status == 401) {
throw new InvalidToken(response.statusText);
} else {
throw new RelayError(`${response.status} ${response.statusText}`);
if (error instanceof NetworkError) {
if (error.responseCode == 400) {
throw new InvalidClientOrHostId(error.message);
} else if (error.responseCode == 401) {
throw new InvalidToken(error.message);
} else {
throw new RelayError(`${error.responseCode} ${error.message}`);
}
} else {
throw new RelayUnreachable(error);
}
}
}

subscribeToMessages(
token: string,
handler: MessageHandler,
messageHandler: MessageHandler,
relayErrorHandler: Function,
relayEventHandler?: RelayEventHandler,
receiveUrl?: string
): Promise<MessageStream> {
const url = receiveUrl ?? this.relayUrl;
return new Promise<MessageStream>((resolve, reject) => {
let resolved = false;
const stream = new EventSource(`${url}?token=${token}`);
stream.onopen = (ev: Event) => {
resolve(stream);
stream.onopen = () => {
if (!resolved) {
resolve(stream);
resolved = true;
}
};
stream.onerror = (ev: Event) => {
reject(new RelayError(ev));
stream.onerror = () => {
if (!resolved) {
// error on connect
reject(new RelayError());
resolved = true;
} else if (relayErrorHandler) {
relayErrorHandler(new RelayError());
}
};
stream.addEventListener('message', (evt: MessageEvent) => {
const message: Message = JSON.parse(evt.data);
handler(message);
messageHandler(message);
});
if (relayEventHandler) {
stream.addEventListener('relay_event', (evt: MessageEvent) => {
const relayEvent: RelayEvent = JSON.parse(evt.data);
relayEventHandler(relayEvent);
});
}
});
}
}
Loading

0 comments on commit 5cbc4cd

Please sign in to comment.