iPhoneアプリでNode.js
iphoneアプリでnode.jsと通信する。
ネイティブアプリでリアルタイムな通信ができるので幅が広がりそう。
環境はMacOSX10で、今回は全部ローカル作業。
objective-cでWebSocket通信
iPhoneアプリとnode.jsで双方向通信するのは、もちろんWebSocketで行う。node.jsをインストールしたことある人はわかると思うが、WebSocket通信はsocket.IOモジュールで行っているのでクライアントサイド(objective-c)もsocket.IOにしたい。ライブラリはsokect.IO-objcを使う。
インストール
xcode側
socket.IO-objcの依存ライブラリをインポート
- cocoa-websocket
- RegexKitLite
- json-framework
- ASIHTTPRequest
cocoa-websocket
https://github.com/erichocean/cocoa-websocket
git cloneでダウンロードし、以下をプロジェクトにインポート。
AsyncSocket/
SocketIO.h
SocketIO.m
RegexKitLite
http://regexkit.sourceforge.net/RegexKitLite/
tarでダウンロードし、以下をプロジェクトにインポート。
RegexKitLite.h
RegexKitLite.m
あとFrameworksに以下をインポート
libicucore.dylib
json-framework
https://github.com/stig/json-framework/
git cloneでダウンロードし、以下をプロジェクトにインポート。
Classes/
ASIHTTPRequest
http://allseeing-i.com/ASIHTTPRequest/
git cloneでダウンロードし、以下をプロジェクトにインポート。
ここに詳しい説明がある
http://allseeing-i.com/ASIHTTPRequest/Setup-instructions
socket.IO-objcをインポート
https://github.com/pkyeck/socket.IO-objc
git cloneでダウンロードし、以下をプロジェクトにインポート。
SocketIO.h
SocketIO.m
node.js(サーバー側)
node.jsとsocket.ioモジュールのインストール
nodeのインストールはnvmコマンドで行う。
git clone https://github.com/creationix/nvm.git ~/.nvm . ~/.nvm/nvm.sh nvm install v0.4.7 nvm use stable npm install socket.io
サンプル
説明
iPhone側から接続し、接続完了後にnode.js側へobjcイベント発火。(もちろんこのobjcという名前はてきとうにつけたイベント名)
node.js側でobjcイベント受信したら3秒後にiPhone側へメッセージを送信。
xcode側
まずxcodeで空のプロジェクトを作る。
名前はSocketIoSampleとした。
SocketIoSampleViewController.h
SocketIODelegateをデリゲート。
#import#import "SocketIO.h" @interface SocketIoSampleViewController : UIViewController @end
SocketIoSampleViewController.m
viewDidLoadメソッドに下記を追記。
- (void)viewDidLoad { [super viewDidLoad]; // WebSocket接続 SocketIO *socketIO = [[SocketIO alloc] initWithDelegate:self]; [socketIO connectToHost:@"localhost" onPort:3000]; } // WebSocket接続完了した場合 - (void) socketIODidConnect:(SocketIO *)socket { NSLog(@"-- socketIODidConnect()"); // objcイベント発火。(node.js側でon('objc', function() {...})でキャッチ) [socket sendEvent:@"objc" withData:[NSDictionary dictionaryWithObject:@"hoge" forKey:@"Key"]]; NSLog(@"-- sendEvent()"); } // node.jsからWebSocketでメッセージが送られてきた場合 - (void) socketIO:(SocketIO *)socket didReceiveEvent:(SocketIOPacket *)packet { NSLog(@"-- didReceiveMessage() >>> data: %@", packet.data); }
node.js側
conn-objc.js
var io = require('socket.io').listen(3000); var timer = require('timers'); // WebSocket接続時 io.sockets.on('connection', function (socket) { console.log('CONNECTION ok'); // iPhoneからのobjcイベント受信時 socket.on('objc', function (data) { console.log('CATCH EVENT ok', data); // iPhoneからのメッセージ受信3秒後に、node.js側からメッセージ送信 timer.setTimeout(function() { socket.emit('messages', { echo: 'from node.js!' }); console.log('SEND MESSAGE ok'); }, 3000); }); });
node.jsを起動
node conn-objc.js
xcodeでビルド
xcode側のログ
SocketIoSample[19935:b303] Opening ws://localhost:3000/socket.io/1/websocket/222774812681844920 SocketIoSample[19935:b303] Connection opened. SocketIoSample[19935:b303] onData 1:: SocketIoSample[19935:b303] connect SocketIoSample[19935:b303] onConnect() SocketIoSample[19935:b303] -- socketIODidConnect() SocketIoSample[19935:b303] send() SocketIoSample[19935:b303] send() >>> 5:::{"args":{"Key":"hoge"},"name":"objc"} SocketIoSample[19935:b303] -- sendEvent() SocketIoSample[19935:b303] doQueue() >> 0 SocketIoSample[19935:b303] setTimeout() SocketIoSample[19935:b303] onData 5:::{"name":"messages","args":[{"echo":"from node.js!"}]} SocketIoSample[19935:b303] setTimeout() SocketIoSample[19935:b303] event SocketIoSample[19935:b303] -- didReceiveMessage() >>> data: {"name":"messages","args":[{"echo":"from node.js!"}]}
node.js側のログ
info - handshake authorized 222774812681844920 debug - setting request GET /socket.io/1/websocket/222774812681844920 debug - set heartbeat interval for client 222774812681844920 debug - client authorized for debug - websocket writing 1:: CONNECTION ok debug - websocket received data packet 5:::{"args":{"Key":"hoge"},"name":"objc"} CATCH EVENT ok { Key: 'hoge' } debug - websocket writing 5:::{"name":"messages","args":[{"echo":"from node.js!"}]} SEND MESSAGE ok debug - emitting heartbeat for client 222774812681844920 debug - websocket writing 2:: debug - set heartbeat timeout for client 222774812681844920 debug - websocket received data packet 2::
特に問題なく通信できた。
これでリアルタイム操作が可能なアプリ作れますね。(・・`。