Skip to content

server-sent events #99

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

Closed
jsanchezfr opened this issue Jan 28, 2021 · 11 comments
Closed

server-sent events #99

jsanchezfr opened this issue Jan 28, 2021 · 11 comments
Labels
question Issue can be closed by providing information

Comments

@jsanchezfr
Copy link

I'm using crow for a lightweight webservices server and I have to implement a CZML one, which requires event-stream.
Is it already supported in any way?

@The-EDev
Copy link
Member

The-EDev commented Jan 28, 2021

If I understand correctly, an event-stream allows a server to push data to a client line by line, rather than in 1 body. This is currently not implemented in Crow (with the exception of static files). Furthermore it might require quite a few changes to how routes work, although such changes would be similar to how Transfer-Encoding: Chunked would work.

@jsanchezfr
Copy link
Author

I have kept trying, but to no result:
I have extended "response":

  • With a pointer to a class of mine ("pEventStream"), which has a function "bool getEvent(std::string &buf)". This function will ask for each new packet to be sent by streaming, until it returns "false", in which case the sending must be finished.
  • "bool is_event_stream()", to identify this new type of sending.
  • New functions:
  template<typename Adaptor>
       void do_stream_event(Adaptor& adaptor)
       {
           if (is_event_stream())
           {
               write_streamed_event(pEventStream, adaptor);
           }
       }
 
   template<typename Adaptor>
   void write_streamed_event(CEventStream * pEventStream, Adaptor& adaptor)
   {
 	  // TODO: Here I have tried sending loops, and everything I could think of...
   }

I have extended "Connection":

  void do_write_general()
  {
      // New case
      if (res.is_event_stream())
      {
          ...
          res.do_stream_event(adaptor_);
          ...
      }
      ...

I have tried a lot of things, without getting any results.
I don't think this kind of botched job will work, and the engine will have to be completely reworked.

@The-EDev
Copy link
Member

I tried passing a lambda instead of the CEventStream object, but the Adaptor template made it quite complicated, I'm also looking into having a custom type of handler (similar to CROW_ROUTE.websocket())

@The-EDev The-EDev added the feature Code based project improvement label Jan 30, 2021
@The-EDev
Copy link
Member

The-EDev commented Feb 1, 2021

I found a much easier way to handle this. It seems that requests in crow store the IO Service object, which is what you need to send data between the server and the client, meaning a method could be easily created to take advantage of that and send data without relying on the Connection object.

only potential hiccup would be SSL (as in OpenSSL) support, since an SSL connection also requires SSL context to function, so some form of that.

I believe most people don't use SSL so I'll try to create some example code that uses the IO Service to send data before the response is completed and will update this comment.

Update:
I edited some bits in the res-push branch, this will not work with SSL, IDK if it'll compile even, it's just a patch to get the ability to send data in chunks.
Here's what I put in a simple CROW_ROUTE to allow chunked encoding, I'm not fully sure on how to use event-stream

res.set_header("Transfer-Encoding", "Chunked");
res.send_chunk(*req.adaptor, "6\r\nHello \r\n");
res.send_chunk(*req.adaptor, "5\r\nWorld\r\n");
res.send_chunk(*req.adaptor, "0\r\n\r\n");

There's no need for res.end() because res.send_chunk() already sets it.

Sorry it took me almost a day to get this done, There was a problem with sending strings because of C strings.

@jsanchezfr
Copy link
Author

Thanks a lot! I'll try!

@jsanchezfr
Copy link
Author

I'm trying, but I'm having problems with the client reading the data from the server correctly.
It could be my code's fault, of course.

@beached
Copy link
Contributor

beached commented Apr 8, 2022

I am having a similar issue with receiving data as it comes in e.g. File uploads
Maybe something that wraps the read_async/write_async events in the ioservice?

Regarding the SSL, I think when I played with it in the past, I am by far not an expert on ASIO, I had to wrap it such that the interface for ssl and non-ssl was type erased and unified. Most things only need to send/recv after the server starts up, I think.

@The-EDev
Copy link
Member

The-EDev commented Apr 8, 2022

@beached I'm not sure this is the same issue @jsanchezfr was facing.. Could you provide more detail?

Crow already has a wrapper for that abstracts plaintext and SSL adaptors. The reason I didn't include the SSL part is because response isn't a template class and I wasn't sure making it one (or making a template function inside it) was the best idea.

@The-EDev The-EDev changed the title event-stream server-sent events Jun 30, 2022
@gittiver gittiver added question Issue can be closed by providing information and removed feature Code based project improvement labels Jul 29, 2024
@gittiver
Copy link
Member

no feature to implement, question is answered.

@harsszegi
Copy link

Hey @gittiver, @The-EDev I have searched the repo for examples on how to do SSE with Crow, but failed. Can any of you provide an example endpoint setup that streams data? Thanks,

@gittiver
Copy link
Member

Hey @gittiver, @The-EDev I have searched the repo for examples on how to do SSE with Crow, but failed. Can any of you provide an example endpoint setup that streams data? Thanks,

Currently server-sent events does not work with Crow, as the request-response mechanism is not fully asynchronous anymore.
You could use web sockets instead in some cases - depends on your exact use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issue can be closed by providing information
Projects
None yet
Development

No branches or pull requests

5 participants