本文开发语言基于Swift 代码参考EchoServer
目录
环境
开始
NIO
测试
-
概念
Blocking-I/O
Non-Blocking-I/O
环境
MacOS安装Xcode即可 所以以下环境搭建基于Ubuntu1604
sudo apt install -y clang libicu-dev git
git clone https://github.com/kylef/swiftenv.git ~/.swiftenv
echo 'export SWIFTENV_ROOT="$HOME/.swiftenv"' >> ~/.zshrc
echo 'export PATH="$SWIFTENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(swiftenv init -)"' >> ~/.zshrc
source ~/.zshrc
swiftenv install 4.0.3
swift --version
关于swiftenv 更多参考swiftenv
开始
mkdir EchoServer
# cd EchoServer
swift package init --type executable
swift build
.build/debug/EchoServer
Hello, world!
NIO
vim Package.swift
// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "EchoServer",
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "1.1.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "EchoServer",
dependencies: ["NIO"]),
]
)
swift package resolve
vim Sources/EchoServer/main.swift
import NIO
// EchoHandler
private final class EchoHandler: ChannelInboundHandler {
public typealias InboundIn = ByteBuffer
public typealias OutboundOut = ByteBuffer
private var count: Int = 0
public func channelRegistered(ctx: ChannelHandlerContext) {
print("channel registered:", ctx.remoteAddress ?? "unknown")
}
public func channelUnregistered(ctx: ChannelHandlerContext) {
print("channel unregistered")
}
public func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
let buffer = self.unwrapInboundIn(data)
print("read:", buffer.getString(at: 0, length: buffer.readableBytes)!)
ctx.write(data, promise: nil)
}
public func channelReadComplete(ctx: ChannelHandlerContext) {
print("read complete")
ctx.flush()
}
public func errorCaught(ctx: ChannelHandlerContext, error: Error) {
print("error: ", error)
ctx.close(promise: nil)
}
}
// Bootstrap
let group = MultiThreadedEventLoopGroup(numThreads: System.coreCount)
let bootstrap = ServerBootstrap(group: group)
.serverChannelOption(ChannelOptions.backlog, value: 256)
.serverChannelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
.childChannelInitializer { channel in
channel.pipeline.add(handler: BackPressureHandler()).then { v in
channel.pipeline.add(handler: EchoHandler())
}
}
.childChannelOption(ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1)
.childChannelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
.childChannelOption(ChannelOptions.maxMessagesPerRead, value: 16)
.childChannelOption(ChannelOptions.recvAllocator, value: AdaptiveRecvByteBufferAllocator())
defer {
try! group.syncShutdownGracefully()
}
let channel = try bootstrap.bind(host: "::1", port: 9999).wait()
print("Server started and listening on \(channel.localAddress!)")
try channel.closeFuture.wait()
print("Server terminated")
测试
- Server
swift build && .build/debug/EchoServer
Compile Swift Module 'EchoServer' (1 sources)
Server started and listening on [IPv6]::1:9999
- Client
telnet localhost 9999
MacOS安装telnet方法: brew install telnet
Trying ::1...
Connected to localhost.
Escape character is '^]'.
- Close
^]
telnet> close
概念
mkdir Node
# cd Node
echo "file content" >> ./file
Blocking I/O
vim bio.js
console.log('start')
const data = require('fs').readFileSync('./file');
console.log('read:', data.toString());
console.log('end');
node bio.js
start
read: file content
end
Non-Blocking I/O
vim nio.js
console.log('start')
require('fs').readFile('./file', (err, data) => {
if (err) throw err;
console.log(data.toString());
});
console.log('end');
node nio.js
start
end
read: file content
参考
swift-nio
苹果公司开源的Swift版Netty:SwiftNIO
Developing a basic Swift Echo Server using Swift-NIO
Overview of Blocking vs Non-Blocking
非同步程式設計和 non-blocking IO