I am trying to capture a UDP video stream within a (fresh) vapor application running in Xcode. The data is being streamed by ffmpeg and I can successfully view the stream on the target machine using VLC, which is also the one running the vapor application, using udp://0.0.0.0:5000
. I have used various bits of Apple documentation to get to the code below. When I run it, I get these lines of output on the console log, but I wonder if they are not relevant:
2021-07-07 17:59:27.102681+0100 Run[10550:2494617] [si_destination_compare] send failed: Invalid argument
2021-07-07 17:59:27.104056+0100 Run[10550:2494617] [si_destination_compare] send failed: Undefined error: 0
In configure.swift:
try setupClient()
This is the client code:
final class FrameHandler : ChannelInboundHandler {
typealias InboundIn = AddressedEnvelope<ByteBuffer>
typealias OutboundOut = AddressedEnvelope<ByteBuffer>
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
// minimal for question
}
func errorCaught(ctx: ChannelHandlerContext, error: Error) {
// minimal for question
}
}
func setupClient() throws {
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let bootstrap = DatagramBootstrap(group: group)
.channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
.channelInitializer { channel in
channel.pipeline.addHandler(FrameHandler())
}
defer {
try! group.syncShutdownGracefully()
}
let channel = try bootstrap.bind(host: "0.0.0.0", port: 5000).wait()
try channel.closeFuture.wait()
}
The problem is that although channelRegistered
and channelActive
are called, followed by a never-ending stream of readComplete
, the important one channelRead
never gets called - neither does errorCaught
. If I comment out the call to setupClient then there is no network activity, however, if it runs then Xcode's network monitor shows activity consistent with the levels in ffmpeg. So, I believe the connection is being set up.
I wonder if the problem is in the way I am setting the handler up? All the examples use echo or reflecting chat examples, so the inbound handler is set up in the closure of the data-writing function using the context rather than adding it in the initialiser (although, the outbound handler is set up in this way).
I'm assuming you're using Vapor 4 which is based on SwiftNIO 2. And in NIO 2, the ChannelHandlerContext
variable is called context
and not ctx
. So if you just rename all your ctx
to context
, I'd assume it'll work.