feat: Initial echo server

This commit is contained in:
2024-11-19 23:03:46 -05:00
commit ab76a4d01c
8 changed files with 252 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
// The Swift Programming Language
// https://docs.swift.org/swift-book
import NIOCore
import NIOPosix
private final class EchoHandler: ChannelInboundHandler {
typealias InboundIn = ByteBuffer
typealias OutboundOut = BackPressureHandler
func channelRead(context: ChannelHandlerContext, data: NIOAny) {
context.write(data, promise: nil)
}
func channelReadComplete(context: ChannelHandlerContext) {
context.flush()
}
func errorCaught(context: ChannelHandlerContext, error: any Error) {
print("error: \(error)")
context.close(promise: nil)
}
}
let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
let bootstrap = ServerBootstrap(group: group)
.serverChannelOption(.backlog, value: 256)
.serverChannelOption(.socketOption(.so_reuseaddr), value: 1)
// set the handlers that are applied.
.childChannelInitializer { channel in
channel.eventLoop.makeCompletedFuture {
try channel.pipeline.syncOperations.addHandler(BackPressureHandler())
try channel.pipeline.syncOperations.addHandler(EchoHandler())
}
}
.childChannelOption(.socketOption(.so_reuseaddr), value: 1)
.childChannelOption(.maxMessagesPerRead, value: 16)
.childChannelOption(.recvAllocator, value: AdaptiveRecvByteBufferAllocator())
defer { try? group.syncShutdownGracefully() }
// First argument is the program path
let arguments = CommandLine.arguments
let arg1 = arguments.dropFirst().first
let arg2 = arguments.dropFirst(2).first
let defaultHost = "::1"
let defaultPort = 9999
struct BindTo {
let host: String
let port: Int
}
let bindTarget: BindTo
switch (arg1, arg1.flatMap(Int.init), arg2.flatMap(Int.init)) {
case let (_, .some(port), _):
bindTarget = .init(host: defaultHost, port: port)
case let (.some(host), _, .some(port)):
bindTarget = .init(host: host, port: port)
case let (.some(host), .none, .none):
bindTarget = .init(host: host, port: defaultPort)
default:
bindTarget = .init(host: defaultHost, port: defaultPort)
}
let channel = try bootstrap.bind(host: bindTarget.host, port: bindTarget.port).wait()
print("Server started and listening on: \(channel.localAddress!)")
try channel.closeFuture.wait()
print("Server closed!")