質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

3810閲覧

socket.ioで常に1つのルームに参加させ続ける方法

h_daido

総合スコア824

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

2クリップ

投稿2018/03/07 02:40

pc向けのweb、SP向けのアプリにそれぞれwebsocket接続するアプリを作っています。

環境

socket.io用サーバー(websocketで利用)
apiサーバー(redisを利用してsocket.ioサーバーと接続している)
フロント(socket.io-client

やりたいこと

ログインユーザーにメッセージがあったときに、pc,sp双方に対してemitしたい

現状やっている方法

  • 「自分一人しか参加していないroom」を作成
  • そのユーザーに対してのメッセージがあったときに、上記roomに対してemit

といったことをしています

困ったこと

原因が特定できていないのですが、websocketのコネクションは繋がっているのに、roomから離脱してしまうということがあります。
そこで、

  • 定期的にroomへの参加をチェック
  • 参加していない場合は参加させる

という処理をしようかと考えています。
(独自のping-pongを作成し、client側でroomに対しての参加をチェックしようかと考えました)

上記のような実装方針で考えているのですが、リクエスト数も無駄に増えるだろうし、ping-pongを独自で実装するのもあまりイケていないように感じます。
実装方針でもなんでもよいのですが、どのようにするのがベストプラクティスなのでしょうか??

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

原因が特定できていないのですが、websocketのコネクションは繋がっているのに、roomから離脱してしまうということがあります。

対象のクライアントと接続は確立された状態のままだけど、そのクライアントがroomから予期せぬタイミングで離脱してしまうことがあるという意味ですか?

勝手に離脱が起きる原因は不明ですけど、プライベートメッセージを送るのであれば、そのクライアントのソケットIDにメッセージをemitする方法もあるので、そちらを代わりに試してみてはいかがでしょうか?

emit-cheatsheet

// sending to individual socketid (private message) socket.to(<socketid>).emit('hey', 'I just met you');

https://socket.io/docs/emit-cheatsheet/

投稿2018/03/07 09:12

HayatoKamono

総合スコア2415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

h_daido

2018/03/07 09:23

ご回答ありがとうございます! 最初ご提示いただいた方法も考えたのですが、 ・SP、PC両方でコネクションをはっていても(同一ユーザーであれば)両方に配信したい ・PCで別タブで開いていても全タブにたいして配信したい などの理由でユーザー単位でのroomを作成し、そこに対してemitするよにしました。 たしかにいちいちroomを作らなくても対応できればベストなのですが...。上記ケースもさらう方法はあるのdしょうか?(例えばsocketに対してuserIdを付与して、特定userIdにemit。とかできればいいと思ったんですが方法がみつからず...)
HayatoKamono

2018/03/07 09:37

あ、なるほど。SP、PC両方というのはそういうことですね。ログインユーザーに対してということであれば、そのユーザーのユーザーIDにクライアントデバイスごとのsocket idを紐付けて、メッセージをemitする時はそのユーザーIDに紐付けられた全てのsocket idにemitするとかはできそうですけど。
h_daido

2018/03/07 09:42

なるほど。ありがとうございます!確かにその方法ならできそうですね。 現在は、socket.ioサーバー <-> redis <-> apiサーバー といった形でつなげているので、面倒だったためroom実装にしていましたが、redisにsocket_idとuser_idのマッピングを保持すればいけそうな気がしてきました。 認証とかめんどくさそうですが...。
h_daido

2018/03/07 10:12

参考になりそうです!ありがとうございます!
h_daido

2018/03/07 13:09

結局、socket.ioサーバー側にuser_idとsocket_idのmappingを保持するかたちで対応できました!スケールアウトした複数サーバーでも問題なく稼働しています。ありがとうございました。
HayatoKamono

2018/03/07 16:15 編集

おー、良かったです!
guest

0

socket.ioを繋ぎっぱなしにする設計に無理があるんじゃないですかね?
特にスマホなら画面OFFにしたり、ブラウザをバックにする頻度は高いでしょうし、
ノートPCも何かの表紙に蓋を閉じてスリープにする頻度は高いですからね。

WebSocketのconnect / disconnectをトリガーにするのではなく、
ネットの接続を休止して当然という作りにした方が良いと思います。
WebSocketベースの運用を辞めるという感じでなんか意味あるのかわからないですけどね…
まぁ、他人のメッセージが1秒以内で瞬時に反映されるだけでも十分なメリットだと思います。

100件までメモリ空間に所持しておいて、
接続する度に全メッセージをDLさせるという設計も良いかと思います。

投稿2018/03/07 04:16

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

h_daido

2018/03/07 09:19

ご回答ありがとうございます! websocketコネクション自体は切れていても問題ない作りにはなっていて、一定時間のインターバルによるチェックの後にreconnectするようになっています。(こちらはsocket.io-clientの機能でそうしているのですが) なんでコネクションは"常に"というわけではないですが、ベストエフォートで繋がった状態になっています。あとオフライン対応なども別途施しています。 なんですが、アプリ起動中、かつオンラインでwebsocketコネクションが繋がっているにもかかわらず、roomから出されるということがあるんですよね。。。 アプリ側はむしろ画面Offなどの動作が頻繁にあるので、その度にwebsocketコネクションが作られるので問題になりづらいのですが、PC側のほうが問題となっています。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問