I am trying to make a simple echo UDP server that sends back all incoming datagrams prefixed with a UTF8 string.
In my attempts to reach this goal, I succeeded in sending back the incoming data, but when I try to prefix this data with the string: "You sent: "
, I get an error writeDataUnsupported
This is my code:
I made a ChannelInboundHandler
called Echo
all it does is: For each incoming datagram, it sends the string "You sent: "
and then the data of the incoming datagram.
final class Echo: ChannelInboundHandler {
typealias InboundIn = ByteBuffer
typealias OutboundOut = ByteBuffer
var wroteResponse = false
static let response = "You sent: ".data(using: .utf8)!
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
if !wroteResponse {
var buffer = ctx.channel.allocator.buffer(capacity: Echo.response.count)
buffer.write(bytes: Echo.response)
ctx.write(self.wrapOutboundOut(buffer), promise: nil)
wroteResponse = true
}
ctx.write(data, promise: nil)
}
func channelReadComplete(ctx: ChannelHandlerContext) {
ctx.flush()
wroteResponse = false
}
}
Then I made a single threaded event loop group and assigned a datagram bootsrap to it. Then I bound the bootstrap to port 4065.
let 🔂 = MultiThreadedEventLoopGroup(numThreads: 1)
let bootstrap = DatagramBootstrap(group: 🔂)
.channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
.channelInitializer { $0.pipeline.add(handler: Echo()) }
defer {
try! 🔂.syncShutdownGracefully()
}
try bootstrap
.bind(host: "127.0.0.1", port: 4065)
.wait()
.closeFuture
.wait()
Why do I always get this writeDataUnsupported
while trying to send the string: "You sent: "
?
For DatagramChannel
you need to wrap your ByteBuffer
into an AddressEnvelope
. Which also means your ChannelInboundHandler should operate on AddressedEnvelope<ByteBuffer>
.