Skip to content

Commit

Permalink
Merge pull request #35 from uhst/next
Browse files Browse the repository at this point in the history
Next
  • Loading branch information
dimitrovs authored Aug 22, 2021
2 parents d5a2b1e + 0fc732a commit fe6b051
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 30 deletions.
102 changes: 72 additions & 30 deletions src/controllers/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ import {
import { RequestWithUser } from '../models/RequestWithUser';
import { Message } from '../models/Message';
import { HostMessage } from '../models/HostMessage';
import {
RelayEvent,
isRelayEvent,
RelayEventType,
} from '../models/RelayEvent';
import { PublicRelay } from '../models/PublicRelay';

interface SenderFunction {
Expand All @@ -39,7 +44,7 @@ export const ping = async (req: Request, res: Response) => {
if (isPublicRelay && !publicHostIdPrefix) {
await getPublicHostIdPrefix(req);
}
res.send({
res.json({
pong: req.query.timestamp ? parseInt(req.query.timestamp as string) : null,
});
};
Expand Down Expand Up @@ -74,7 +79,7 @@ export const initHost = async (req: Request, res: Response) => {
hostId: hostId,
hostToken: signToken(hostToken),
};
res.send(config);
res.json(config);
}
};

Expand All @@ -99,7 +104,7 @@ export const initClient = (req: Request, res: Response) => {
const config: ClientConfiguration = {
clientToken: signToken(clientToken),
};
res.send(config);
res.json(config);
}
};

Expand Down Expand Up @@ -220,19 +225,24 @@ const findPrefixByUrl = (relays: PublicRelay[], url: string): string => {
};

const broadcastToClients = (
clients: Map<String, SenderFunction>,
clientIds: string[],
hostId: string,
message: Message
): Map<string, boolean> => {
let result = new Map<string, boolean>();
for (let clientId of clientIds) {
const sendToClient = clients.get(clientId);
if (sendToClient) {
sendToClient(message);
result.set(clientId, true);
): Map<string, boolean> | null => {
const clients = hosts.get(hostId);
if (clients) {
const clientIds = getConnectedClientIds(hostId);
let result = new Map<string, boolean>();
for (let clientId of clientIds) {
const sendToClient = clients.get(clientId);
if (sendToClient) {
sendToClient(message);
result.set(clientId, true);
}
}
return result;
} else {
return null;
}
return result;
};

const sendMessageToClient = (
Expand All @@ -247,7 +257,7 @@ const sendMessageToClient = (
sendToClient({
body: req.body,
});
res.sendStatus(200);
res.json({});
} else {
res.sendStatus(400);
}
Expand All @@ -270,7 +280,7 @@ const sendMessageToHost = (
body: req.body,
};
sendToHost(message);
res.sendStatus(200);
res.json({});
} else {
res.sendStatus(400);
}
Expand All @@ -281,19 +291,16 @@ const broadcastMessage = (
res: Response,
hostToken: HostTokenPayload
) => {
const clients = hosts.get(hostToken.hostId);
if (clients) {
const clientIds = [];
const message: Message = {
body: req.body,
};
for (let clientId of clients.keys()) {
if (clientId !== hostToken.hostId) {
clientIds.push(clientId.toString());
}
}
let result = broadcastToClients(clients, clientIds, message);
res.json(result);
const message: Message = {
body: req.body,
};
const result = broadcastToClients(hostToken.hostId, message);
if (result) {
let jsonObject: any = {};
result.forEach((value, key) => {
jsonObject[key] = value;
});
res.json(jsonObject);
} else {
res.sendStatus(400);
}
Expand All @@ -308,13 +315,35 @@ const addClient = (
) => {
const disconnect = () => {
clientConnections.delete(clientId);
if (hosts.get(hostId)?.size === 0) {
const clients = hosts.get(hostId);
if (!clients || clients.size === 0) {
// last client has left, remove host
hosts.delete(hostId);
} else {
if (hostId === clientId) {
// host has disconnected, notify clients
broadcastToClients(hostId, <RelayEvent>{
eventType: RelayEventType.HOST_CLOSED,
body: hostId,
});
} else {
// client has disconnected, notify host
const sendToHost = clients.get(hostId);
if (sendToHost) {
sendToHost(<RelayEvent>{
eventType: RelayEventType.CLIENT_CLOSED,
body: clientId,
});
}
}
}
};
clientConnections.set(clientId, (message: Message) => {
res.sse.data(message);
if (isRelayEvent(message)) {
res.sse.event('relay_event', message);
} else {
res.sse.data(message);
}
});
req.on('error', disconnect);
res.on('error', disconnect);
Expand All @@ -332,3 +361,16 @@ const isHostConnected = (hostId: string): boolean => {
}
return result;
};

const getConnectedClientIds = (hostId: string): string[] => {
const clientIds: string[] = [];
const clients = hosts.get(hostId);
if (clients) {
for (let clientId of clients.keys()) {
if (clientId !== hostId) {
clientIds.push(clientId.toString());
}
}
}
return clientIds;
};
14 changes: 14 additions & 0 deletions src/models/RelayEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Message } from './Message';

export enum RelayEventType {
CLIENT_CLOSED = 'client_closed',
HOST_CLOSED = 'host_closed',
}

export interface RelayEvent extends Message {
eventType: RelayEventType;
}

export function isRelayEvent(obj: any): obj is RelayEvent {
return obj.eventType !== undefined;
}

0 comments on commit fe6b051

Please sign in to comment.