Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External Server for Events when using Serverless #59

Closed
jameswoodley opened this issue Oct 21, 2024 · 1 comment
Closed

External Server for Events when using Serverless #59

jameswoodley opened this issue Oct 21, 2024 · 1 comment
Labels
seen I've seen and read this issue and I'll try find some time soon to work on it.

Comments

@jameswoodley
Copy link

Hi there,

I know SSE and Websockets don't work well on serverless architecture such as Vercel, but I was hoping to host the areas that require these things on a stateful server, then the rest of the app remains in the Vercel environment.

I'm testing locally, and all seems well, but the /events request is throwing a CORS error. I have created a Svelte API with the OPTIONS verb setting it to allow everything essentially, but still getting the error. Do you know if SSE can work across domains?

EventCoordinator Service:

import type { RequestHandler } from './$types';
import { json } from '@sveltejs/kit';
import { produce } from 'sveltekit-sse';
import sessions from '$lib';

export const POST: RequestHandler = async ({ request }) => {
	const sessionId = request.headers.get('X-User-ID') ?? '';
	console.log('EVENTS REQUESTED FOR ', sessionId);

	return produce(
		async function start({ emit }) {
			const cancel = (message?: string) => {
				console.log('SSE Connection Cancelled');
				if (message) {
					console.error(message);
				}

				sessions.delete(sessionId);
			};

			if (!sessionId) {
				cancel('Client Session Id not found');
			}

			// Give the session it's own emitter, also tells us the client is "online"
			sessions.set(sessionId, emit);

			return () => cancel();
		},
		{
			// When client goes offline, remove their session
			stop() {
				if (!sessionId) {
					return;
				}

				console.log('Stopping Session', sessionId);
				sessions.delete(sessionId);
			}
		}
	);
};

export const PUT: RequestHandler = async ({ request }) => {
	const sessionId = request.headers.get('X-User-ID') ?? '';
	console.log('MESSAGE SENT TO ', sessionId);

	const { event, payload } = (await request.json()) as {
		event: string;
		payload: object;
	};
	const session = sessions.get(sessionId);
	if (session) {
		session(event, JSON.stringify(payload));
		return json({}, { status: 202 });
	} else {
		return json({}, { status: 204 });
	}
};

export const OPTIONS: RequestHandler = async ({ request }) => {
	return new Response(null, {
		status: 204,
		headers: {
			'Access-Control-Allow-Origin': '*',
			'Access-Control-Allow-Headers': '*',
			'Access-Control-Allow-Methods': 'POST, PUT, OPTIONS',
			'Access-Control-Max-Age': '86400'
		}
	});
};

Vercel Service:

onMount(() => {
		source('https://event-coordinator.max-514.workers.dev/events', {
			close({ connect }) {
				connect();
			},
			options: {
				headers: {
					'X-User-ID': data.user.id
				}
			}
		})
			.select(`MessageAccepted`)
			.subscribe((mailboxId: string) => {
				if (mailboxId) {
					console.log('Mailbox Id', mailboxId);
					invalidate(`mailbox:summary`);
				}
			});
	});

Console errors in Vercel service:
image

@razshare razshare added the seen I've seen and read this issue and I'll try find some time soon to work on it. label Oct 22, 2024
@jameswoodley
Copy link
Author

Ignore me - I found the headers prop in the produce function!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
seen I've seen and read this issue and I'll try find some time soon to work on it.
Projects
None yet
Development

No branches or pull requests

2 participants