1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
// The Swift Programming Language
// https://docs.swift.org/swift-book
import ArgumentParser
import Foundation
import Logging
import NIO
@main
struct swiftGopher: ParsableCommand {
@Option(name: [.short, .long], help: "Hostname used for generating selectors")
var gopherHostName: String = "localhost"
@Option(name: [.short, .long])
var host: String = "0.0.0.0"
@Option(name: [.short, .long])
var port: Int = 8080
@Option(name: [.customShort("d"), .long], help: "Data directory to map")
var gopherDataDir: String = "./example-gopherdata"
@Flag(help: "Disable full-text search feature")
var disableSearch: Bool = false
@Flag(help: "Disable reading gophermap files to override automatic generation")
var disableGophermap: Bool = false
public mutating func run() throws {
let eventLoopGroup = MultiThreadedEventLoopGroup(
numberOfThreads: System.coreCount
)
defer {
try! eventLoopGroup.syncShutdownGracefully()
}
let localGopherDataDir = gopherDataDir
let localGopherHostName = gopherHostName
let localPort = port
let localEnableSearch = !disableSearch
let localDisableGophermap = disableGophermap
let logger = Logger(label: "com.navanchauhan.gopher.server")
let serverBootstrap = ServerBootstrap(
group: eventLoopGroup
)
.serverChannelOption(
ChannelOptions.backlog,
value: 256
)
.serverChannelOption(
ChannelOptions.socketOption(
.so_reuseaddr
),
value: 1
)
.childChannelInitializer { channel in
channel.pipeline.addHandlers([
BackPressureHandler(),
GopherHandler(
logger: logger,
gopherdata_dir: localGopherDataDir,
gopherdata_host: localGopherHostName,
gopherdata_port: localPort,
enableSearch: localEnableSearch,
disableGophermap: localDisableGophermap
),
])
}
.childChannelOption(
ChannelOptions.socketOption(
.so_reuseaddr
),
value: 1
)
.childChannelOption(
ChannelOptions.maxMessagesPerRead,
value: 16
)
.childChannelOption(
ChannelOptions.recvAllocator,
value: AdaptiveRecvByteBufferAllocator()
)
let defaultHost = host
let defaultPort = port
let channel = try serverBootstrap.bind(
host: defaultHost,
port: defaultPort
).wait()
logger.info("Server started and listening on \(channel.localAddress!)")
try channel.closeFuture.wait()
logger.info("Server closed")
}
}
|