【问题标题】:writeDataUnsupported in ChannelInboundHandler (Swift-NIO)ChannelInboundHandler (Swift-NIO) 中不支持 writeData
【发布时间】:2018-08-22 05:54:04
【问题描述】:

我正在尝试制作一个简单的 echo UDP 服务器,它可以发回所有以 UTF8 字符串为前缀的传入数据报。

在我试图达到这个目标的过程中,我成功地发回了传入的数据,但是当我尝试在这个数据前加上字符串:"You sent: ",我收到一个错误writeDataUnsupported

这是我的代码:

我创建了一个名为EchoChannelInboundHandler,它所做的只是:对于每个传入的数据报,它发送字符串"You sent: ",然后是传入数据报的数据。

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
    }
}

然后我创建了一个单线程事件循环组并为其分配了一个数据报引导程序。然后我将引导程序绑定到端口 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()

为什么我在尝试发送字符串时总是得到这个writeDataUnsupported"You sent: "

【问题讨论】:

    标签: swift swift4 swift-nio


    【解决方案1】:

    对于DatagramChannel,您需要将ByteBuffer 包装成AddressEnvelope。这也意味着您的 ChannelInboundHandler 应该在 AddressedEnvelope<ByteBuffer> 上运行。

    【讨论】:

    • 谢谢诺曼,这是否记录在某处? (DatagramChannel 与AddressedEnvelope's 一起使用的事实)
    • 我认为没有...我会在 SwiftNIO 中添加一些文档和示例
    【解决方案2】:

    按照 Norman Maurer 的建议,要使 ChannelInboundHandlerAddressedEnvelope<ByteBuffer> 上运行,您可以重写 Echo,使其看起来更像:

    final class Echo: ChannelInboundHandler {
        typealias  InboundIn  = AddressedEnvelope<ByteBuffer>
        typealias OutboundOut = AddressedEnvelope<ByteBuffer>
    
        static let response = "You sent: ".data(using: .utf8)!
    
        func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
            var incomingEnvelope = unwrapInboundIn(data)
            var buffer = ctx.channel.allocator.buffer(capacity: Echo.response.count + incomingEnvelope.data.readableBytes)
            buffer.write(bytes: Echo.response)
            buffer.write(buffer: &incomingEnvelope.data)
    
            let envelope = AddressedEnvelope(remoteAddress: incomingEnvelope.remoteAddress, data: buffer)
            ctx.write(wrapOutboundOut(envelope), promise: nil)
        }
    
        func channelReadComplete(ctx: ChannelHandlerContext) {
            ctx.flush()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 2018-02-15
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多