NIO入門

本文開發(fā)語言基于Swift 代碼參考EchoServer

目錄

環(huán)境

MacOS安裝Xcode即可 所以以下環(huán)境搭建基于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

關(guān)于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")

測(cè)試

  • 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

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于多路復(fù)用 很多人用過InputStream和OutputStream接口,用來操作文件、Socket等等 IO...
    Gemini閱讀 353評(píng)論 0 0
  • 這兩天了解了一下關(guān)于NIO方面的知識(shí),網(wǎng)上關(guān)于這一塊的介紹只是介紹了一下基本用法,沒有系統(tǒng)的解釋NIO與阻塞、非阻...
    Ruheng閱讀 7,250評(píng)論 5 48
  • NIO(Non-blocking I/O,在Java領(lǐng)域,也稱為New I/O),是一種同步非阻塞的I/O模型,也...
    閃電是只貓閱讀 3,279評(píng)論 0 7
  • 此時(shí)的你不夠努力,導(dǎo)致現(xiàn)在的你無能為力!
    在下石麒麟閱讀 189評(píng)論 0 0
  • 時(shí)間7:00-7:30 書頁:15-34 書名:《心理咨詢師》 書摘: 感想:這部分知識(shí)是基礎(chǔ),我沒什么聯(lián)想和太多...
    不要多愁善感閱讀 222評(píng)論 0 1

友情鏈接更多精彩內(nèi)容