rstudio / plumber

Turn your R code into a web API.
https://www.rplumber.io
Other
1.38k stars 256 forks source link

HTTP server sent events #955

Open ElianHugh opened 3 weeks ago

ElianHugh commented 3 weeks ago

I would like it to be possible to serve server sent events (SSE) in plumber. I have been trying to write event-streams using plumber, but have found that whilst I can get the "open" event to fire, I can't send any "message" events because plumber doesn't have a way of sending messages without the return value of the function.

# Example event-stream opening
#' @get /sse
#' @serializer contentType list(type="text/event-stream")
function(res, req) {
    "data: Hello world.\n\n"
}

The above results in the connection successfully being opened, and the connection kept alive, but it also means that only the "open" event is sent (and spammed).

SSE are typically easier (for users) to write and use in comparison to websockets, and doesn't require a custom protocol to be handled. Whilst websockets are definitely useful, the bidirectional nature of them is often overkill.

My naive assumption is that the main issue is that res doesn't have a write function. This is technically different from sockets in that this a uni-directional HTTP connection. I understand that websockets have been looked at (e.g. #723, #419), but websockets are -- as far as I understand -- a slightly different implementation to SSE.

I have tried looking through httpuv for a way to do this without plumber, but I've admittedly had difficulty on finding a way to get it to work!

Examples

SSE

Thanks!

louisaslett commented 3 weeks ago

Coincidentally I was just trying to do this too, in my case I thought HTMX with SSE plus {plumber} would be a lovely combo!

After a bit of poking around, I discovered that {httpuv} does not, and probably will not, support HTTP/2. I believe {plumber} is built on {httpuv} and so inherits this limitation. Sadly, as far as I understand Server Sent Events (SSE) needs HTTP/2, though happy to be corrected if that's not right. So regrettably {plumber} and {httpuv} are no-go for this. Indeed, I'm not aware of any HTTP/2 capable server package for R?

Anyhow, I'm not a {plumber} maintainer, so would welcome one of them weighing in with a more definitive answer, but unless I hear otherwise I'm abandoning my own explorations as I don't fancy building an HTTP/2 server first just to get SSE in R!

ElianHugh commented 3 weeks ago

Coincidentally I was just trying to do this too, in my case I thought HTMX with SSE plus {plumber} would be a lovely combo!

Ha, incidentally I was doing the exact same thing!

After a bit of poking around, I discovered that {httpuv} does not, and probably will not, support HTTP/2. I believe {plumber} is built on {httpuv} and so inherits this limitation. Sadly, as far as I understand Server Sent Events (SSE) needs HTTP/2, though happy to be corrected if that's not right. So regrettably {plumber} and {httpuv} are no-go for this. Indeed, I'm not aware of any HTTP/2 capable server package for R?

That's a good point, I didn't realise httpuv didn't use HTTP/2. As far as I can tell, SSE does not require HTTP/2, but it does make it more usable/feasible. HTTP/1's limited number of connections (6 vs HTTP/2's 100) makes SSE slow. So, I think technically it should be possible right now (albeit hamstrung)?