Skip to content

Commit

Permalink
Merge pull request ionic-team#4 from jokester/fix-spa-serving
Browse files Browse the repository at this point in the history
Fix spa serving
  • Loading branch information
jokester authored Feb 2, 2024
2 parents 8c8af0a + a7c88cf commit 1ef1cb7
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 70 deletions.
17 changes: 12 additions & 5 deletions demo/src/pages/v1/:namespace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,23 @@ function usePageState(namespace: string): PageState {
const defaultOrigin = getDefaultOrigin();
const socket = io(`${defaultOrigin}/v1/${namespace}`);

socket.onAny((event, clientEvent, payload) => {
const now = new Date().toISOString();
if (['connect', 'disconnect', 'connect_error'].includes(event)) {
for (const event of ['connect', 'disconnect', 'connect_error']) {
socket.on(event, (...rest: unknown[]) => {
logger('socket event', event, rest);
const now = new Date().toISOString();

setState(prev => ({
...prev,
state: event,
logLines: [`${now}: ${event}`, ...prev.logLines].slice(0, 100),
}));
} else if (clientEvent === 'ping') {
const now = new Date().toISOString();
});
}

socket.onAny((event, clientEvent, payload) => {
logger('wildcard event', event, clientEvent, payload);
const now = new Date().toISOString();
if (clientEvent === 'ping') {
const ping = payload as PingMessage;
const delay = (Date.now() - Date.parse(ping.timestamp)).toFixed(2);

Expand Down
16 changes: 8 additions & 8 deletions server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ import {closeSioSockets, prepareTcpConnect, waitSignal} from './utils';

const logger = debug('limb:server');

const distDir = path.join(__dirname, 'dist');
const distFound = fs.existsSync(distDir);

interface ServerGroup {
http: http.Server;
io: sio.Server;
Expand All @@ -26,11 +23,13 @@ function initServer(): ServerGroup {
httpServer.on('request', (req, res) => {
logger('request', req.url);

if (distFound) {
const distDir = path.join(__dirname, 'dist');
if (fs.existsSync(distDir)) {
serveHandler(req, res, {
public: distDir,
// FIXME
rewrites: [{source: '/topics/*', destination: '/index.html'}],
// route for SPA
// NOTE static files take precedence over this
rewrites: [{source: '/*', destination: '/index.html'}],
cleanUrls: true,
directoryListing: false,
trailingSlash: false,
Expand Down Expand Up @@ -60,8 +59,9 @@ function initServer(): ServerGroup {
.of(/^\/v1\/[-\w:]+$/)
.on('connection', socket => onV1Connection(socket.nsp, socket));

const v2 = ioServer.of('/v2');
v2.on('connection', socket => onV2Connection(v2, socket));
ioServer
.of(/^\/v2\/[-\w:]+$/)
.on('connection', socket => onV2Connection(socket.nsp, socket));

return {
http: httpServer,
Expand Down
89 changes: 37 additions & 52 deletions server/namespace-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,12 @@ import {ClientCommandBase, ClientCommands} from '../types/namespace-v2';

const logger = debug('limb:server:v2');

// events should not be broadcasted
// i.e. a socket won't receive them from peer sockets
const csInteractionEvents: ReadonlySet<string> = new Set([
// client internal
'connect_error',
'connect',
// server internal
'disconnecting',
'disconnect',
'error',
// client-server interactions
'join',
'leave',
'welcome',
'pong',
]);

export function onV2Connection(
namespace: sio.Namespace,
socket: sio.Socket
): void {
logger('connection', socket.id);

function onInternalError(error: unknown): void {
logger('error handling ', socket.id, error);
socket.disconnect(true);
}

socket.send('welcome', {socketId: socket.id});

socket.on('disconnecting', (reason: unknown) => {
logger('disconnecting', socket.id, reason);
});
Expand All @@ -45,43 +21,47 @@ export function onV2Connection(

socket.on('error', (error: unknown) => {
logger('error', socket.id, error);
onInternalError(socket, error);
});

socket.on('join', (msg: ClientCommands['join']) => {
logger('join', socket.id, msg.room);
socket.on('message', (event, payload) => {
try {
socket.join(`room:${msg.room}`);
handleUserMessage(namespace, socket, event, payload);
} catch (e) {
onInternalError(e);
onInternalError(socket, e);
}
});

socket.on('leave', (msg: ClientCommands['join']) => {
logger('join', socket.id, msg.room);
try {
socket.leave(`room:${msg.room}`);
} catch (e) {
onInternalError(e);
}
});
socket.send('sys:welcome', {socketId: socket.id});
}

socket.onAny((event: string, clientMessage: ClientCommandBase) => {
try {
if (csInteractionEvents.has(event)) {
return;
} else if (event === 'ping') {
socket.send('pong', {
from: clientMessage.from,
});
forwardMessage(namespace, socket, event, clientMessage);
} else {
forwardMessage(namespace, socket, event, clientMessage);
}
logger('topic event', event);
} catch (e) {
onInternalError(e);
function handleUserMessage(
namespace: sio.Namespace,
socket: sio.Socket,
event: string,
_payload: ClientCommandBase
) {
logger('user message', socket.id, event, _payload.nonce);

switch (event) {
case 'sys:ping': {
const now = new Date().toISOString();
socket.send('sys:pong', {timestamp: now});
break;
}
});
case 'room:join': {
const payload = _payload as ClientCommands[typeof event];
socket.join(`room:${payload.room}`);
break;
}
case 'room:leave': {
const payload = _payload as ClientCommands[typeof event];
socket.leave(`room:${payload.room}`);
break;
}
default:
forwardMessage(namespace, socket, event, _payload);
}
}

function forwardMessage(
Expand All @@ -106,3 +86,8 @@ function forwardMessage(
}
});
}

function onInternalError(socket: sio.Socket, error: unknown): void {
logger('error handling ', socket.id, error);
socket.disconnect(true);
}
10 changes: 5 additions & 5 deletions types/namespace-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ export interface ClientCommandBase {
}

export interface ClientCommands extends Record<string, ClientCommandBase> {
join: ClientCommandBase & {room: string};
leave: ClientCommandBase & {room: string};
ping: ClientCommandBase & {timestamp: string};
'room:join': ClientCommandBase & {room: string};
'room:leave': ClientCommandBase & {room: string};
'sys:ping': ClientCommandBase;
}

export interface ServerCommands {
welcome: {socketId: string};
pong: ClientCommandBase;
'sys:welcome': {socketId: string};
'sys:pong': ClientCommandBase;
}

0 comments on commit 1ef1cb7

Please sign in to comment.