KituraでWebSocketを動かす

# KituraでWebSocketを動かす
## はじめに
Twitterを眺めていたら、

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Working with <a href="https://twitter.com/hashtag/WebSockets?src=hash">#WebSockets</a> in a <a href="https://twitter.com/hashtag/Kitura?src=hash">#Kitura</a> based server <a href="https://t.co/csdKHVT6uG">https://t.co/csdKHVT6uG</a> <a href="https://twitter.com/hashtag/swiftlang?src=hash">#swiftlang</a> <a href="https://twitter.com/hashtag/serversideswift?src=hash">#serversideswift</a></p>&mdash; Kitura Swift (@KituraSwift) <a href="https://twitter.com/KituraSwift/status/821691635708915712">2017年1月18日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

KituraでWebSockerが使えるようになったというツイートを見かけたので、記事を書いてみることにしました。

## 環境
Mac OS X El Capitan 10.11.6
Swift 3.0.2

## プロジェクトのセットアップ

```bash
$ mkdir SocketServer
$ cd SocketServer
$ swift package init --type executable
```

```
SocketServer
├── Package.swift
├── Sources
│   └── main.swift
└── Tests
```
上記のようにファイルが生成されます。

## パッケージの追加

```swift:Package.swift
import PackageDescription

let package = Package(
    name: "SocketServer",
    dependencies: [
        .Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 1, minor: 5),
        .Package(url: "https://github.com/IBM-Swift/Kitura-WebSocket", majorVersion: 0, minor: 5),
        .Package(url: "https://github.com/IBM-Swift/HeliumLogger.git", majorVersion: 1, minor: 5)
    ]
)
```

以下のフレームワークをインポートしました。

- **Kitura**
HTTP Server用のWebフレームワーク

- **Kitura-WebSocket**
Kitura用のWebSocketフレームワーク

- **HeliumLogger**
Swift用のロギングフレームワーク

ここでいちど`$ swift build`を実行することで、リポジトリからのクローンと依存ライブラリのコンパイルを行います。

```bash
$ swift build
・・・
Compile Swift Module 'Socket' (3 sources)
Compile Swift Module 'LoggerAPI' (1 sources)
Compile Swift Module 'Cryptor' (10 sources)
Compile Swift Module 'KituraTemplateEngine' (1 sources)
Compile Swift Module 'SwiftyJSON' (2 sources)
Compile Swift Module 'HeliumLogger' (2 sources)
Compile Swift Module 'SSLService' (1 sources)
Compile CHTTPParser utils.c
Compile CHTTPParser http_parser.c
Linking CHTTPParser
Compile Swift Module 'KituraNet' (35 sources)
Compile Swift Module 'KituraWebSocket' (9 sources)
Compile Swift Module 'Kitura' (42 sources)
Compile Swift Module 'SocketServer' (1 sources)
Linking ./.build/debug/SocketServer
```

## WebSocketサーバの実装

```swift:Sources/main.swift
import Foundation

import Kitura
import KituraWebSocket

import HeliumLogger

HeliumLogger.use()

let router = Router()

WebSocket.register(service: MyService(), onPath: "websocket")

Kitura.addHTTPServer(onPort: 8090, with: router)

Kitura.run()
```

```swift:Sources/MyService.swift
import Foundation

import KituraWebSocket
import LoggerAPI

class MyService: WebSocketService {
    public func connected(connection: WebSocketConnection) {}

    public func disconnected(connection: WebSocketConnection, reason: WebSocketCloseReasonCode) {}

    public func received(message: Data, from: WebSocketConnection) {
        from.send(message: message)
    }
    public func received(message: String, from: WebSocketConnection) {
        Log.info("Got message \(message)... sending it back")
        from.send(message: message)
    }
}
```

今回は、8090番ポートに対してwebsocketというルーティングを追加しました。
WebSocketサーバに接続してテキストを送信すると、送信した内容をそのまま返信するようなオウム返しサービスになっています。

## ソースのコンパイル

```bash
$ swift build
Compile Swift Module 'SocketServer' (2 sources)
Linking ./.build/debug/SocketServer
```

## 実行
```bash
$ .build/debug/SocketServer
・・・
[2017-01-20T14:32:12.158+09:00] [VERBOSE] [Router.swift:67 init(mergeParameters:)] Router initialized
[2017-01-20T14:32:12.170+09:00] [VERBOSE] [Kitura.swift:70 run()] Starting Kitura framework...

[2017-01-20T14:32:12.170+09:00] [VERBOSE] [Kitura.swift:80 start()] Starting an HTTP Server on port 8090...
[2017-01-20T14:32:12.171+09:00] [INFO] [HTTPServer.swift:85 listen(on:)] Listening on port 8090
```

HeliumLoggerを使用したので、上記のようなログが出力されています。

以下のURIでWebSocketサーバが立っているので、
`ws://localhost:8090/websocket`

下記のようなWebSocketクライアントを使用することで、接続確認ができます。
http://www.websocket.org/echo.html


## 参考
https://developer.ibm.com/swift/2017/01/17/working-websockets-kitura-based-server/

## あとがき
初めてQiitaの記事を書いてみました。
Kitura自体、IBMが公開した去年の2月に少し触ってやめてしまっていたのですが、久しぶりに触ってみると、いろいろ機能が追加されてたり、だいぶ使いやすくなっていて驚いています。
これからしばらく、Kituraを触りながら記事を書いていこうと思います。