question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support Server-Sent Events (SSE) with adapter-node

See original GitHub issue

Describe the bug While migrating a sapper app to svelte-kit / adapter-node, I came across a feature that seems to be missing. Namely, the ability to create custom middleware that can handle Server-Sent Events or other long-lived connections that send data to the response stream without closing the connection. Since the handle hook requires returning Response | Promise<Response>, thus closing the connection, it does not support this. Nor have I found any other way to res.write(); using endpoints.

Information about your SvelteKit Installation:

Diagnostics
System:
    OS: Linux 4.4 Ubuntu 20.04.1 LTS (Focal Fossa)
    CPU: (8) x64 Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
    Memory: 7.97 GB / 15.94 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
Binaries:
    Node: 14.5.0 - ~/.nvm/versions/node/v14.5.0/bin/node
    npm: 6.14.5 - ~/.nvm/versions/node/v14.5.0/bin/npm
npmPackages:
    @sveltejs/kit: ^1.0.0-next.68 => 1.0.0-next.68
    svelte: ^3.37.0 => 3.37.0
    vite: ^2.1.5 => 2.1.5
  • Using node-adapter

Severity Adds a bit of friction for migrating from Sapper, reduces feature parity, and will require me to either a) regress to polling the server from the client, or b) write a custom adapter for every project that needs SSEs. (which I’m not sure that this even helps for the development environment anyways)

Additional context Issue #334 seems relevant.

Also originally asked within discord chat but no one seems to know the answer, which is why I am submitting this issue.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:13
  • Comments:13 (1 by maintainers)

github_iconTop GitHub Comments

6reactions
caytercommented, Apr 11, 2021

@babeard After going through https://vitejs.dev/guide/api-plugin.html#configureserver, I believe we can try the below:

  1. Come up with a middleware with the method signature function (req, res, next) => {}.
  2. Configure the middleware in svelte.config.cjs’s vite.plugins. (this is for svelte-kit dev)
  3. Come up with a forked adapter-node that allows polka to use the same middleware. (this is for node build/index.js after svelte-kit build with the forked adapter-node)

I haven’t tested it but I think it should work. There’s a drawback to this approach though, we’d have to match the SSE routes ourselves.

Update

I had tested it, the approach above works though I’m still trying to figure out how we can pass in the middleware to adapter-node so that it will configure polka to use them during svelte-kit build step.

svelte.config.cjs

const sveltePreprocess = require('svelte-preprocess');
const node = require('@sveltejs/adapter-node');
const pkg = require('./package.json');
const bodyParser = require('body-parser');
const sseMiddleware = require('./src/middlewares/sse.cjs');

/** @type {import('@sveltejs/kit').Config} */
module.exports = {
	// Consult https://github.com/sveltejs/svelte-preprocess
	// for more information about preprocessors
	preprocess: sveltePreprocess(),
	kit: {
		adapter: node({
                   out: 'build',

                   // TODO: We probably can update `adapter-node` to provide this callback which 
                   // is to ensure `node build/index.js` works. As this isn't implemented yet, you can 
                   // simply run `svelte-kit build` and manually add the middleware to polka instance's 
                   // use method at the end of `build/index.js` file.
                   configureServer(polkaInstance) {
                     polkaInstance.use(bodyParser.json());
                     polkaInstance.use(sseMiddleware);
                   }
                 }),

                ...

		vite: {
                        ...

                         // This is to ensure `svelte-kit dev` works.
			plugins: [
				(() => ({
					name: 'configure-server',
					configureServer(server) {
						server.middlewares.use(bodyParser.json());
						server.middlewares.use(sseMiddleware);
					}
				}))()
			],

                         ...
		}
	}
};

./src/middlewares/sse.cjs

let clients = [];
const messages = [];

module.exports = (req, res, next) => {
	if (req.url === '/messages') {
		switch (req.method) {
			case 'GET':
				const headers = {
					'Content-Type': 'text/event-stream',
					Connection: 'keep-alive',
					'Cache-Control': 'no-cache'
				};
				res.writeHead(200, headers);

				const data = `messages: ${JSON.stringify(messages)}\n\n`;
				res.write(data);

				const clientId = Date.now();
				const newClient = {
					id: clientId,
					res
				};

				clients.push(newClient);

				req.on('close', () => {
					console.log(`${clientId} Connection closed`);
					clients = clients.filter((client) => client.id !== clientId);
				});

				break;

			case 'POST':
				const newMessage = req.body;
				messages.push(newMessage);
				res.end(`${JSON.stringify(newMessage)}\n`);

				clients.forEach((client) =>
					client.res.write(`newMessage: ${JSON.stringify(newMessage)}\n`)
				);

				break;
		}

		return;
	}

	next();
};
2reactions
mustofa-idcommented, Jan 22, 2022

as this #3384 changes, are now possible to implement SSE through endpoint?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Server-sent events - Web APIs | MDN
Defines all the features that handle connecting to a server, receiving events/data, errors, closing a connection, etc. Examples. Simple SSE demo ...
Read more >
How To Use Server-Sent Events in Node.js to Build a ...
Step 1 – Building the SSE Express Backend. In this section, you will create a new project directory. Inside of the project directory...
Read more >
Server-Sent Events | NestJS - A progressive Node.js framework
Server -Sent Events. Server-Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via HTTP...
Read more >
Server-Sent Events (SSE) problem with SSL/HTTPS
Hello I am developing a web application in React that receives SSE data from an Express server with Nginx. SERVER.JS
Read more >
Understanding Server-Sent Events With Node.js - Medium
In this article let's build a simple node.js data streaming endpoint with a technique called server-sent events (SSE).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found