Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

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'] こういう感じの配列が渡ってくると思いますのでご注意を。

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

参考

mito_log
ベトナム・ハノイ拠点の個人デベロッパ。東南アジア向けに素敵なサービスと文化を作るべく模索中。ベトナムで1年半農業。newbie skateboarder、ハノイITもくもく会毎週土曜朝9時頃 → https://bit.ly/2Oe9Ehk
http://mitolab.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした