Hello everyone, I want to do long polling on NIO for my chatbot, is it a good idea to do this on NIO? I tried to do it through recursion on a combine, but in this way the memory is not freed, which will lead to a server crash sooner or later, I thought to try NIO at the same time, but I can’t how and where to start moving (If you have any ideas or developments, there was would be grateful)
For a chatbot, or any long lived connection, websockets are an easy way to bootstrap a streaming connection until you need or want to move to a lighter protocol (for most users, probably never). Vapor offers websocket connectivity built in, and
URLSession even offers
URLSessionWebSocketTask (and someday I'll finish Alamofire's integration of that), so you can get up and running pretty quickly.
(On a side note, Apple OS versions that coincide with iOS 14.5 - 147 have a
URLSessionWebSocketTask bug where, if the connection is closed too quickly after you receive messages, the last messages you received (within a certain time window) will be dropped by the client. If you need to support such clients, requiring a delay between last message and close on the server will work around the issue. 100ms should be enough, but you should test it.
i can't use websocket, cause chatbot api support only long polling(
You probably want to move this into #related-projects:swiftnio for the SwiftNIO answers.
But yes, absolutely, you can use SwiftNIO as both a server and/or a client to do long-polling or in fact anything else -- including bidirectional streaming -- over HTTP/1.1, HTTP/2, WebSocket or whatever other protocol suits your needs.
I do have an example project which implements bidirectional streaming with AsyncHTTPClient and URLSession as clients and pure NIO as well as Vapor as servers; all over HTTP/1.1. It runs every combination as in AsyncHTTPClient <-> Vapor; AsyncHTTPClient <-> pure NIO; URLSession <-> Vapor; URLSession <-> pure NIO.
What the example does concretely is: The client sends
!1\n and when the server receives it, it replies with the same text. Upon receiving
!1\n back from the server, the client waits 1 second and sends
!2\n, etc... After going back and forth 10 times, the client determines that bidirectional streaming works just fine and finishes the HTTP request.
Now whilst my example isn't a full-blown chat server, it can absolutely be made into one.
tl;dr Yes, you can use NIO for clients and servers; but also URLSession, AsyncHTTPClient and Vapor.
If you really want to use just one long-poll per HTTP request, that's obviously possible too but with bidirectional streaming, you can do an entire chat session in just one single HTTP request.