I am currently thinking/working my way through making a NIO based RTSP Client. If you did not already know RTSP is modeled after HTTP; so a lot of the same patterns used there can be carried over.
I am trying to write client to do some basic stuff. Right now I want to be able to do a simple OPTIONS
call and get the data back.
let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
defer {
try! group.syncShutdownGracefully()
}
let connection = try! RTSPConnection
.connect(
to: .makeAddressResolvingHost("192.241.179.45", port: 554),
on: group.next()
)
.wait()
let options = try connection.options().wait()
print(options)
// This will never unblock as we don't close the channel
try connection.wait()
The signature of RTSPConnection.options()
looks like this func options() -> EventLoopFuture<String>
. At least for now, all I am trying to do is get the raw output from the server and return it as a EventLoopFuture
.
The try connection.options().wait()
is sending (with proper CRLF)
OPTIONS rtsp://192.241.179.45:554/ RTSP/1.0
CSeq: 0
The server is responding (with proper CRLF):
RTSP/1.0 200 OK
CSeq: 0
Date: Tue, Jul 06 2021 21:27:11 GMT
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER
So far so good.
Now the question, what is a "best practice" way to get that server response into the EventLoopFuture<String>
returning from the options()
method? I've looked at async-http-client and postgres-nio for inspiration and they seem to each do it differently.
I am inclined to believe that I should be making a ChannelHandler
, specifically one that conforms to RemovableChannelHandler
, and registering it to look for the corresponding CSeq
in the response and removing the handler once seen. Is this right or is there a better way?