How to produce a response body with asynchronously created body chunks in Swift Vapor

536 views Asked by At

I am looking into the Swift Vapor framework.

I am trying to create a controller class that maps data obtained on an SSL link to a third party system (an Asterisk PBX server..) into a response body that is sent over some time down to the client.

So I need to send received text lines (obtained separately on the SSL connection) as they get in, without waiting for a 'complete response' to be constructed.

Seeing this example:

return Response(status: .ok) { chunker in
  for name in ["joe\n", "pam\n", "cheryl\n"] {
      sleep(1)
      try chunker.send(name)
  }

  try chunker.close()
}

I thought it might be the way to go.

But what I see connecting to the Vapor server is that the REST call waits for the loop to complete, before the three lines are received as result.

How can I obtain to have try chunker.send(name) send it's characters back the client without first waiting for the loop to complete?

In the real code the controller method can potentially keep an HTTP connection to the client open for a long time, sending Asterisk activity data to the client as soon as it is obtained. So each .send(name) should actually pass immediately data to the client, not waiting for the final .close() call.

Adding a try chunker.flush() did not produce any better result..

1

There are 1 answers

3
tanner0101 On BEST ANSWER

HTTP requests aren't really designed to work like that. Different browsers and clients will function differently depending on their implementations.

For instance, if you connect with telnet to the chunker example you pasted, you will see the data is sent every second. But Safari on the other hand will wait for the entire response before displaying.

If you want to send chunked data like this reliably, you should use a protocol like WebSockets that is designed for it.