iphaaw
iphaaw

Reputation: 7204

SwiftNIO: TCP Server not sending data back

I have written my own handler for SwiftNIO but I cannot get it to send anything.

class MyHandler: ChannelInboundHandler
{
    public typealias InboundIn = ByteBuffer
    public typealias OutboundOut = ByteBuffer
    
    public func channelRead(context: ChannelHandlerContext, data: NIOAny)
    {
        let message = "The weather is sunny.\n"
        let length = message.utf8.count
        
        var buffer = context.channel.allocator.buffer(capacity: length)
        buffer.writeString(message)

        let out = self.wrapOutboundOut(buffer)
        context.write(out, promise: nil)
    }
    
    public func channelReadComplete(context: ChannelHandlerContext)
    {
        context.flush()
    }
    
    public func errorCaught(context: ChannelHandlerContext, error: Error)
    {
        print("error: ", error)
        context.close(promise: nil)
    }
}

If I just leave the channelRead function as below it successfully echoes the incoming text:

public func channelRead(context: ChannelHandlerContext, data: NIOAny)
{
    context.write(data, promise: nil)
}

What am I doing wrong?

Upvotes: 0

Views: 362

Answers (1)

Johannes Weiss
Johannes Weiss

Reputation: 54071

You're not doing anything wrong, this should work just fine. It'll send back The weather is sunny.\n every time any data is received.

I also tried it and it works:

$ nc localhost 9999
How's the weather?
The weather is sunny.
How are you?
The weather is sunny.

The complete code I used was

import NIO

class MyHandler: ChannelInboundHandler
{
    public typealias InboundIn = ByteBuffer
    public typealias OutboundOut = ByteBuffer
    
    public func channelRead(context: ChannelHandlerContext, data: NIOAny)
    {
        let message = "The weather is sunny.\n"
        let length = message.utf8.count
        
        var buffer = context.channel.allocator.buffer(capacity: length)
        buffer.writeString(message)

        let out = self.wrapOutboundOut(buffer)
        context.write(out, promise: nil)
    }
    
    public func channelReadComplete(context: ChannelHandlerContext)
    {
        context.flush()
    }
    
    public func errorCaught(context: ChannelHandlerContext, error: Error)
    {
        print("error: ", error)
        context.close(promise: nil)
    }
}

let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
defer {
    try! group.syncShutdownGracefully()
}

let bootstrap = ServerBootstrap(group: group)
    .serverChannelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
    .childChannelInitializer { channel in
        channel.pipeline.addHandler(MyHandler())
    }

let serverChannel = try bootstrap.bind(host: "localhost", port: 9999).wait()
try serverChannel.closeFuture.wait()

Upvotes: 1

Related Questions