サーバーとの連携アプリで更新された最新の状態を取得するのにバックグラウンドフェッチだと負荷もかかり、かっこ良くないので、サーバー側からプッシュできたら便利だな...と思いついたのでWebSocketをRubyMotionから使ってみる事にしました。
サーバ側(nodejs)
今回は簡単にサーバーを作成するためにnodejsのwsというモジュールを使います。
ws: a node.js websocket implementation
s
すでにnodejsが入っていればnpmで簡単インストールです。
npm install -g ws
インストールするとwscatというユーティリティがインストールされるので、これを使うと簡単にWebSocketの送受信テストが行えます。ポート8080にてサーバーモードで待ち受けを行います。
wscat -l 8080
これで単純な送受信用サーバー完成
クライアント側(iOS)
SocketRocketというframeworkを使います。CocoaPodsにあるので、インストールは簡単です。す〜いす〜い。
SocketRocket Objective-C WebSocket Client
# motion-cocoapdsインストール時
app.pods do
pod 'SocketRocket'
end
Rake pod:install
コード的にはSRWebSocketを生成するのと、delegateを作成します。
注:実際にはStoryboradでUIを作ってIBで連結しており、myMessageはUITextFieldに連結しています。また、ProMotionを使っているので、on_loadに初期化コードを書いています。
class MainScreen < PM::Screen
extend IB
outlet :myMessage, UITextField
def on_load #ProMotion初期化
url = NSURL.URLWithString("ws://127.0.0.1:8080")
@socket = SRWebSocket.alloc.initWithURLRequest(NSURLRequest.requestWithURL(url))
@socket.delegate = self
@socket.open
end
def sendMessage #メッセージ送信
p "Send: #{myMessage.text}"
@socket.send(myMessage.text)
myMessage.text = ""
end
def webSocketDidOpen(webSocket)
p "Socket Open!"
end
def webSocket(webSocket, didReceiveMessage:message)
p "Receive: #{message.description}"
end
def webSocket(webSocket, didFailWithError:error)
p "Error : #{error.description}"
end
def webSocket(webSocket, didCloseWithCode:code,reason:reason)
p "Close"
end
end
動作テスト
nodejsで作ったサーバー側で文字を入力するとクライアント側で受信します。また、文字列を送信するとサーバー側に送信されます。うまくいかない場合は待ち受けポートとかIPに注意してください。
これをうまく使ってプロトコルを決めて動作させれば、サーバー側からのプッシュに応じたリアルタイム動作ができると思います。ステキ。
拡張
サーバー接続状況のエラー表示等はNoticeViewを追加して表示させるとかっこよくできますよ、と自分メモ。
notice = WBErrorNoticeView.errorNoticeInView(self.view,
title:"Socket Error", message:"Check your network connection.")
notice.show