19
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

socket.ioで書いてもすぐ消える落書きアプリを作ってみた

Last updated at Posted at 2015-03-31

socket.ioを最近勉強していて、こないだは簡単なチャットアプリを作ってみたので、今度は落書き共有アプリを作ってみました。perlin noiseも勉強してみたかったので、1次のperlin noiseで線を描くようにしてみました。使い方あってるか怪しいですが...。

こんな感じ

gif

ソース

https://github.com/mitolog/AwkwardLineShare
※ SIOSocket.m/.hも少し改変したので、pod install後、個別に上書きしたら動くと思います

アプリの機能

  • perlin noiseでいびつな線を描ける
  • 線は一定期間で消える
  • 描いた線をsocketをつないでいる各端末と共有できる

アプリの大まかな仕組み

  • View ControllerのviewDidLoad()でソケット通信開始、及びタイマーでdrawRectを一定間隔で再描画するように各サブビューにsetNeedsDisplayを送る
  • owner(自身)とmember(他端末)用のUIViewサブビュー(AwkwardLineView)を用意
  • ownerの場合は、touchイベントをオーバーライドしてバッファ用の配列に座標を溜める
  • memberの場合は、socket.ioのコールバックで座標の配列をもらい、バッファ用の配列と差し替える
  • 各サブビューのdrawRectでバッファ配列に溜めた座標を使って描画処理

引っかかったところ

drawRectがsetNeedsDisplayで再描画されない!

これについては、別でまとめたのでそちらをご参照ください。

SIOSocketでクライアント側からemitする場合のパラメータは複数取れる

クライアント側ではこのようにemitしています

ViewController.m
[self.socket emit:@"draw" args:@[points, self.socket.socketId]];

pointsの中身は @[@{x=1,y=0},@{x=1.1,y=0.1}...] こんな感じで、CGPointのdictionaryの配列となっています。
self.socket.socketIdは、NSString、自身のsocketidになります。

で、これをSIOSocketのメソッドに渡すと、このように展開され、

objc_socket.emit('draw', [{"X":186.2593,"Y":82.25927}], 'KEW30FqD9rNAjdahAABL')

'draw'っていう名前のイベントとして、2つのパラメータを持ってサーバ側に送られます。

利用しているAPIは公式ドキュメントでいくとこれかなと。
Socket#emit(name:String[, …]):Socket

で、サーバ側では、こんな感じでキャッチできます。

awkwardLineShareServer.js
    socket.on('draw', function (data,socketId) {
        io.emit('update', [data, socketId]);
    });
});

つまり何がいいたいかというと、今まで、1つのパラメータしか取れないと思っていたんですね。。そのパラメータをjsonとかにして。でも複数とれるんだ、ということが今回分かりました。

サーバ側からemitする場合のパラメータは複数取れない?

ただ、サーバ側からemitする場合は、io.emit('update', [data, socketId]);こんな感じで配列として渡さないとエラーになってしまいましたので、そこもご注意を。

SIOSocketで受け取る際は、

ViewController.m
[self.socket on: @"update" callback: ^(SIOParameterArray *args)
{
    // Update draw line data
    [self updateDrawLineWithAry:args[0]];
}];

こんなふうに、args(配列)でラップされて渡ってきます。おそらくここもパラメータを複数取れるように配慮されて配列なんだと思いますが、なぜかサーバ側で1つしかパラメータをとれなかったので、args[0]として1番目の要素に @[@[CGPointsのDictionary], 'ソケットid'] こういう感じの配列が渡ってくると思いますのでご注意を。

※ もしかしたらやり方がまずいだけで、サーバ側も複数のパラメータをとれるかもしれません。正しいやり方が分かる方いらっしゃればおしえてください!

参考

19
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?