Apple 新开源了一个 Swift 相关的项目,叫 swift-nio

Apple 新开源了一个 Swift 相关的项目,叫 swift-nio,是一个事件驱动的非阻塞的网络框架,用来写高性能网络应用。看来官方真的继续在往 Server-Side 方面努力.GitHub.

SwfitNIO 的目标是支持所有可以运行 Swift 的平台。目前,SwfitNIO 可以在 macOS 和 Linux 上运行,包括:

Ubuntu 14.04+

macOS 10.12+

基本架构

SwfitNIO 包含了几种基本构建块,所有的 SwfitNIO 应用程序都是由这几种组件组成的。

EventLoopGroup

EventLoop

Channel

ChannelHandler

Bootstrap

ByteBuffer

EventLoopPromise 和 EventLoopFuture

EventLoop 是 SwfitNIO 最基本的 IO 原语,它等待事件的发生,在发生事件时触发某种回调操作。在大部分 SwfitNIO 应用程序中,EventLoop 对象的数量并不多,通常每个 CPU 核数对应一到两个 EventLoop 对象。一般来说,EventLoop 会在应用程序的整个生命周期中存在,进行无限的事件分发。

EventLoop 可以组合成 EventLoopGroup,EventLoopGroup 提供了一种机制用于在各个 EventLoop 间分发工作负载。例如,服务器在监听外部连接时,用于监听连接的 socket 会被注册到一个 EventLoop 上。但我们不希望这个 EventLoop 承担所有的连接负载,那么就可以通过 EventLoopGroup 在多个 EventLoop 间分摊连接负载。

目前,SwiftNIO 提供了一个 EventLoopGroup 实现(MultiThreadedEventLoopGroup)和两个 EventLoop 实现(SelectableEventLoop 和 EmbeddedEventLoop)。

MultiThreadedEventLoopGroup 会创建多个线程(使用 POSIX 的 pthreads 库),并为每个线程分配一个 SelectableEventLoop 对象。

SelectableEventLoop 使用选择器(基于 kqueue 或 epoll)来管理来自文件和网络 IO 事件。EmbeddedEventLoop 是一个空的 EventLoop,什么事也不做,主要用于测试。

 Channels、ChannelHandler、ChannelPipeline 和 ChannelHandlerContext

尽管 EventLoop 非常重要,但大部分开发者并不会与它有太多的交互,最多就是用它创建 EventLoopPromise 和调度作业。开发者经常用到的是 Channel 和 ChannelHandler。

每个文件描述符对应一个 Channel,Channel 负责管理文件描述符的生命周期,并处理发生在文件描述符上的事件:每当 EventLoop 检测到一个与相应的文件描述符相关的事件,就会通知 Channel。

ChannelPipeline 由一系列 ChannelHandler 组成,ChannelHandler 负责按顺序处理 Channel 中的事件。ChannelPipeline 就像数据处理管道一样,所以才有了这个名字。

ChannelHandler 要么是 Inbound,要么是 Outbound,要么两者兼有。Inbound 的 ChannelHandler 负责处理“inbound”事件,例如从 socket 读取数据、关闭 socket 或者其他由远程发起的事件。Outbound 的 ChannelHandler 负责处理“outbound”事件,例如写数据、发起连接以及关闭本地 socket。

ChannelHandler 按照一定顺序处理事件,例如,读取事件从管道的前面传到后面,而写入事件则从管道的后面传到前面。每个 ChannelHandler 都会在处理完一个事件后生成一个新的事件给下一个 ChannelHandler。

ChannelHandler 是高度可重用的组件,所以尽可能设计得轻量级,每个 ChannelHandler 只处理一种数据转换,这样就可以灵活组合各种 ChannelHandler,提升代码的可重用性和封装性。

我们可以通过 ChannelHandlerContext 来跟踪 ChannelHandler 在 ChannelPipeline 中的位置。ChannelHandlerContext 包含了当前 ChannelHandler 到上一个和下一个 ChannelHandler 的引用,因此,在任何时候,只要 ChannelHandler 还在管道当中,就能触发新事件。

SwiftNIO 内置了多种 ChannelHandler,包括 HTTP 解析器。另外,SwiftNIO 还提供了一些 Channel 实现,比如 ServerSocketChannel(用于接收连接)、SocketChannel(用于 TCP 连接)、DatagramChannel(用于 UDP socket)和 EmbeddedChannel(用于测试)。

 Bootstrap

SwiftNIO 提供了一些 Bootstrap 对象,用于简化 Channel 的创建。有些 Bootstrap 对象还提供了其他的一些功能,比如支持 Happy Eyeballs。

目前 SwiftNIO 提供了三种 Bootstrap:ServerBootstrap(用于监听 Channel),ClientBootstrap(用于 TCP Channel)和 DatagramBootstrap(用于 UDP Channel)。

 ByteBuffer

SwiftNIO 提供了 ByteBuffer,一种快速的 Copy-On-Write 字节缓冲器,是大部分 SwiftNIO 应用程序的关键构建块。

ByteBuffer 提供了很多有用的特性以及一些“钩子”,通过这些钩子,我们可以在“unsafe”的模式下使用 ByteBuffer。这种方式可以获得更好的性能,代价是应用程序有可能出现内存问题。在一般情况下,还是建议在安全模式下使用 ByteBuffer。

 EventLoopPromise 和 EventLoopFuture

并发代码和同步代码之间最主要的区别在于并非所有的动作都能够立即完成。例如,在向一个 Channel 写入数据时,EventLoop 有可能不会立即将数据冲刷到网络上。为此,SwiftNIO 提供了 EventLoopPromise和 EventLoopFuture,用于管理异步操作。

EventLoopFuture实际上是一个容器,用于存放函数在未来某个时刻的返回值。每个 EventLoopFuture对象都有一个对应的 EventLoopPromise,用于存放实际的结果。只要 EventLoopPromise 执行成功,EventLoopFuture 也就完成了。

通过轮询的方式检查 EventLoopFuture 是否完成是一种非常低效的方式,所以 EventLoopFuture 被设计成可以接收回调函数。也就是说,在有结果的时候回调函数会被执行。

EventLoopFuture负责处理调度工作,确保回调函数是在最初创建 EventLoopPromise 的那个 EventLoop 上执行,所以就没有必要再针对回调函数做任何同步操作。

SwiftNIO 的设计哲学

SwiftNIO 的目标是要成为强大的网络应用程序开发框架,但并不想为所有的层次抽象提供完美的解决方案。SwiftNIO 主要专注在基本的 IO 原语和底层的协议实现上,将其他层次的抽象留给广大的社区去构建。SwiftNIO 将成为服务器端应用程序的构建块,但不一定就是应用程序直接拿来使用的框架。

对性能有很高要求的应用程序可能会直接使用 SwiftNIO,减少上层抽象所带来的开销。SwiftNIO 可以帮助这些应用程序在提升性能的同时降低维护成本。SwiftNIO 还为某些场景提供了有用的抽象,高性能的网络服务器可以直接使用这些抽象。

大家也可以看GitHub上面的原版介绍

目前有一些例子,演示了如何使用 SwiftNIO。

聊天客户端:

github

聊天服务器端:

GitHub

Echo 客户端:

github

Echo 服务器端:

GitHub

Http 服务器:

github


我对swift的vapor框架情有独钟,据了解vpaor已经开始适配swif-nio了。等vapor3的release版本出来后,到时候会第一时间去适配自己的服务。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容