Swift开源:AppMateServer - 基于 Websocket 的简易通讯服务器

PamelaEPLF 8年前
   <p><img src="https://simg.open-open.com/show/0c4259a96dffae0fc9ae754c7c9675c9.png"></p>    <h2>AppMateServer</h2>    <p>这是 AppMate 的服务端。</p>    <p>它是一个基于 Websocket 的简易通讯服务器,编写语言为 swift 。工程的 master 分支可在 <strong>Xcode 8.2</strong> 及以上编译,当前只能工作在 macOS(10.12+) 平台。</p>    <p>See Also</p>    <ul>     <li><a href="/misc/goto?guid=4959733846861899902" rel="nofollow,noindex">AppMateClient</a></li>     <li><a href="/misc/goto?guid=4959733846955484923" rel="nofollow,noindex">AppMateBrowser</a></li>    </ul>    <h2>前置说明</h2>    <p>AppMate 其实是我们小组内部的一个尝试,正式服务的 server 端是用 Nodejs 实现的。用 swift 重写这个项目的核心框架主要是想确认下知名 swift web 框架Perfect 的使用手感和稳定性到底如何。其中 websocket 组件是基于官方 PerfectlySoft/Perfect-WebSockets 自行定制的 Event-Driven 版本,Pull Request 见此。</p>    <p>尝试这个项目另外一点,其实也想知道使用 swift 可以做到什么程度,以及对比其他 server 端(e.g. Nodejs)的优劣势。</p>    <p>最后是关于平台兼容性,这确实是一个问题。因为Swift Foundation 目前还处于早期阶段,一些模块还没有做到完全跨平台,不幸的是在这个项目中会使用到其中的个别模块(e.g. Stream , DateFormatter )。另外用到了改版后的GCD,当前只能工作在 macOS(10.12+) 平台。</p>    <h2>编译运行</h2>    <p>首先是 clone 工程,SPM 安装依赖</p>    <pre>  git clone https://github.com/c98/AppMateServer.git  cd AppMateServer  swift package fetch  swift package generate-xcodeproj  open *.xcodeproj</pre>    <p>缺省的服务端端口是 8011,你可以在 main.swift 中修改。</p>    <p>在 Xcode 中运行服务端,你会看到如下输出:</p>    <pre>  Starting HTTP server on 0.0.0.0:8011 with document root ./webroot</pre>    <p>这表示服务端已启动,正等待监听,剩下就是手机端AppMateClient 和浏览器端AppMateBrowser 的访问了。</p>    <h2>文件组织</h2>    <p>server 端主要依赖了 Perfect 框架,项目的源码文件在 Sources 目录下。</p>    <pre>  main.swift: 服务端配置,router handler 设定,主运行循环  handler.swift: 配置 websocket 的 message handler  pubsub.swift: 基于 Publish/Subscribe 的一套简单的通讯模式  plugins.swift: 插件管理,负责注册模块的订阅关系  sessions.swift: 核心插件,负责管理 websocket 应用级会话,包括连接进来、断开、心跳控制等  Test.swift: 一个测试插件,用来订阅手机端发来的 log,进行信息重组再推送给浏览器端</pre>    <h2>服务端通讯架构图</h2>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a745609ae2e1b2ca65f8fada16e0c185.png"></p>    <h2>后记</h2>    <p>AppMate 系列项目是最近一周整理的,踩了一点坑,不过整体而言还算顺利。</p>    <p>如果说有什么想说的,我觉得 server 端会是一个不错的话题。</p>    <p>我大概还算是一名 iOS 开发,虽然近半年基本上不怎么写 iOS 代码了,主要是在搞 Nodejs 后端 和 前端应用。</p>    <p>上文说过我们在内部使用的是 Nodejs 版本,而在这个系列中的 server 端是采用 swift 编写的,这其实是一个偶然也可以说是无奈之举。</p>    <p>我倒是很想尝试在 App 端用 swift 写一点东西,但是因为一些客观条件的限制,目前还无法在生产环境中使用这门语言,转而想用这门语言在一些内部系统的后台中做点事情 ;)</p>    <p>初次使用 swift 编写 server 端应用,碰到了很多问题,给我印象深刻的是 swift 的 值语义 ,我以为这个东西很简单,因为这也不是什么新东西,但是在实际编码时忽略了这个简单的概念而处处碰壁。Array 等基础类型是值语义的,尽管语言内部是做了引用语义+COW 优化,由于长期习惯了 for in 的引用语义(OC/js),让我在这个坑里爬了好久。</p>    <p>给我带来一定冲击的是 Optional,虽然从理解上而言不是特别绕,但是真的使用时,发现很多时间都是花在 Optional 上。它强制了我必须认真对待变量为空的可能, 一定程度上提高了编码的可靠性,现在是想偷一点懒都不行,即便只是写一个测试应用。</p>    <p>swift 真的是一个熟悉了才能提高编码效率的语言,初次接触还是比较难受的,好在现在 Xcode 的错误和 autofix 提示都做的非常好了。</p>    <p>同样是开发这个服务端,Nodejs 在开发效率上远超 swift,但是出错率也会高于 swift。有几方面原因,一个是语言本身的严谨度,js 就是太动态了,什么都没有限制,都可以做,这一点真不知道是该让人爱还是恨,swift 天生严谨,限制重重。第二个原因是社区的质量和支持度,以服务端而言,我觉得单从开发体验上,Perfect 离 Node 还有相当距离,尽管 Perfect 目前已经算得上是社区中相对较为完善的 web 框架了。</p>    <p>swift 基础类型比较丰富,如果 Fundation 和其他核心库能完成标准化、跨平台,我觉得作为服务端语言新秀也是相当有吸引力的 ;)</p>    <p> </p>    <p> </p>    <p> </p>