kdunglas

Joined 8 years ago

Karma
1,176
Submissions
62
Member since
Sep 12
Founder of Les-Tilleuls.coop (tech worker-owned cooperative).

Creator of mercure.rocks, frankenphp.dev and api-platform.com and vulcain.rocks. Co-maintainer of the Symfony framework and the Caddy web server.

[ website: https://dunglas.fr, twitter: https://twitter.com/dunglas ]

View on Hacker News

Recent submissions

Comment · 1 year ago
WebSub cannot be used by browsers because browsers cannot receive POST requests. WebSub is for server to server communications. Mercure is basically WebSub over SSE.

The draft has been discussed several times on the HTTP WG.

Comment · 1 year ago
Yes, as it 's "just" SSE, this works pretty well behind Cloudflare and other similar solutions. Mercure also automatically sends the NGINX-specific headers required to allow unbuffered connections.

Native mobile apps are also entirely supported. It's a very common use case. Most mobile languages have SSE client libraries.

Comment · 1 year ago
Once the connection is upgraded, you loose all metadata included in the HTTP headers (because it’s not HTTP) and all protections relying on it. Also CORS and SOP can be bypassed: https://dev.to/pssingh21/websockets-bypassing-sop-cors-5ajm

Even very experienced teams make mistake with this kind of things. See for instance, this Kubernetes vulnerability: https://goteleport.com/blog/kubernetes-websocket-upgrade-sec...

Of course you can reimplement everything by hand (and you must if you use WebSockets), but with SSE/Mercure you don't have to because it's plain old HTTP.

Comment · 1 year ago
This limitation is gone with HTTP/2 and HTTP/3 and the Mercure hub automatically use the most recent protocol supported by the browser.
Comment · 1 year ago
Hi, Mercure author here.

Indeed that's how it works. One of the key point of the solution is that you don't need anything client-side. The native EventSource class is all you need (but you can use more advanced SSE client libraries if wanted).

Reconnection and state reconciliation are achieved automatically. The hub implements all the needed features: it stores sent events and automatically resend them at reconnection time if they have been lost. It's possible to do this transparently because browsers will automatically send the ID of the last received message in a Last-Event-ID header when reconnecting. This feature is just often not implemented by SSE servers (because it’s not trivial to do).

It's also possible to ask events received since a specific ID, matching one or several topics just by passing the query parameters defined in the protocol section.

By the way, we are working on a new website that will make these things more clear.

Comment · 1 year ago
Hi, Mercure author here.

WebSockets are hard to secure (they totally bypass CORS as well as other browser built-in protections), don't work (yet) with HTTP/3 and for most use cases require to implement many features by yourself: reconnection in case of network failure, refetch of lost messages, authorization, topic mechanism…

Mercure, which is built on top of SSE (it's more an extension to SSE than an alternative to it) fix these issues.

However, SSE (as well as WebSockets) can be hard to use with stacks not designed to handle persistent connections such as PHP, serverless, most web servers proxying Ruby, Python etc apps. Even for languages designed to handle persistent connections, it's often more efficient and easier to manage persistent connections with ah-hoc software running on dedicated hardware.

That's what Mercure allows. Mercure provides a "hub", a server that will maintain the persistent connections with the browsers, store events, and re-send them in case of network issues (or if asked for old messages by a client). To broadcast a message to all connected users, the server app (or even a client) can just send a single POST request to the hub. The hub will also check that clients are authorized to subscribe or publish to a given topic (that's why JWT is used).

The reference implementation is written in Go, as a module for the Caddy web server, and his very efficient/optimized (it can handle thousands of persistent connections on very small machines).

Install a Mercure hub and you have all these features available without having to write any code. Client-side, no SDK is required, you can embrace the built-in EventSource JavaScript class.

Comment · 1 year ago
Comment · 1 year ago
Comment · 2 years ago
The Symfony framework (PHP) provides a similar feature, which also relies on LISTEN/NOTIFY and FOR UPDATE SKIP LOCKED: https://symfony.com/doc/current/messenger.html#doctrine-tran...

It also supports many other backends including AMQP, Beanstalkd, Redis and various cloud services.

This component, called Messenger, can be installed as a standalone library in any PHP project.

(Disclaimer: I’m the author of the PostgreSQL transport for Symfony Messenger).

Comment · 2 years ago
That's not the case with other engines able to keep the booted app in memory to handle several requests (FPM doesn't support this).
Comment · 2 years ago
Comment · 2 years ago
Optionally, you can embed the PHP scripts in the final binary using a Go feature similar to `include_bytes`: https://frankenphp.dev/docs/embed/

But for PHP, it's even simpler: PHP is available as a C library, and we just use it. (libphp can be embedded using static compilation, or used as a dynamic library, we support both).

Comment · 2 years ago
This means that in addition to any PSR-7 implementation, you can run apps using HttpFoundation (Symfony, Laravel, Drupal, etc) and "legacy" code using superglobals without the need for an adapter.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton