11

私は過去数か月間 Socket.io を使用して、チャット ルーム、キック/禁止/モデレーター/フレンドなどを備えたかなり複雑なチャット アプリケーションを開発してきました。

開発の過程で、アプリを何度か書き直しましたが、まだコードと戦っています。

私は JavaScript がとても好きですが、アプリケーションが成長するにつれ、それを維持するのは本当に大変だと感じています。チャット アプリケーションの作成方法に関する膨大な量の「チュートリアル」を読みましたが、それらはすべて最も基本的な側面のみをカバーしています。GitHub のすべてのサンプル アプリ、および Web で見つけたほとんどのチャット アプリケーションでさえ同じことが言えます (それらのほとんどは、ユーザー管理のない単純な IM です)。

たとえば、ユーザーを部屋から追い出すなど、いくつかのユースケースは私にはあまりにもばかげているように思えます。

  • モデレーターがキックボタンをクリック -> サーバーにイベントを送信
  • サーバーはユーザー名をソケットとペアにします(または、すべてのユーザーにブロードキャストし、クライアント側でフィルターします)->キックイベントを彼に発行します
  • ユーザーはサーバーにログアウト イベントを発行し、キックされたというメッセージも表示されます (ログアウトは罰の実装に過ぎません)。
  • ユーザーはチャット ルームのユーザー リストから削除されます -> 現在のユーザー リストをルーム内のすべてのユーザーに送信します

これはそれほど複雑ではないように見えますが、UI を管理するためにクライアント側で発生するすべてのコールバックを追加すると (私は AngularJS を使用するため、イベントを使用してコントローラー間の通信を行います)、サーバー側の大量のコールバックも追加します。すべてがノンブロッキングであるため、これをテストするのは本当に難しいと思います。

クライアント側には別の問題があり、複数の場所でソケット イベントをリッスンする必要があるため、一種のシングルトン グローバル ソケット オブジェクトを用意し、複数の場所でイベント リスナーをフックする必要があります。

私は何か間違ったことをしていますか、それともこのコールバック地獄は、それを回避する方法がないWebソケットで作業した結果ですか?

このようなアプリケーションの開発を容易にする方法はありますか? たとえば、Socket.io の代替技術は? これまでのところ、最後のコミットが 5 か月前のNowJSと、本当にクールなmeteorしか見つかりませんでしたが、ウェブサイトを見ると、実際には安定していないようです。

4

5 に答える 5

7

友達の約束を使ってください。jQueryにはそれらが組み込まれていますが、nodejs 側ではqライブラリを使用できます。それらなしで非同期コードを書かないでください! 慣れるまでには少し時間がかかりますが、考え方に慣れれば、非同期コードを書くのは簡単です。

コールバック コードに関するユーティリティ関数を提供するasyncのようなライブラリもあります。しかし、人気にだまされてはいけません。約束は甘い。

非同期コードのテストでは、テストが完了したときに呼び出すことができる単純な関数を提供するnodeunitよりも遠くに行く必要がないため、好きなだけ実行できます。done()

于 2012-09-23T17:47:19.187 に答える
3

おっと、それを実際の問題に分解しましょう。定義されているものはあまりありません。

部屋からユーザーを蹴る:

  • モデレーターが[削除]ボタンをクリックします(emitにはroomIDとuserIDが含まれている必要があります)
  • サーバーコードは、ユーザーをRoomオブジェクトから削除し、ユーザーIDがキックされたというメッセージをルーム内の各ユーザーに送信します。以前にユーザーのソケットjoin(roomID)があった場合、そのサーバーコードは次のようになります。

    sio.sockets.to(roomID).emit('kicked', { userID: uid });
    

それで全部です。クライアントコードでは、この「キックされた」イベントを受け取り、次のようなコードを使用する必要があります。

if (data.removedUserID == myUserID)
    alert('You have been kicked by moderator');
else
    removeUserFromList(userID);

悪意のあるユーザーが禁止を無視するクライアントを作成する可能性があるため、クライアントにメッセージを送信させないでください。

複数の場所でソケットイベントをリッスンする必要があります

なんで?「複数の場所」とは正確にはどういう意味ですか?

このようなアプリケーションの開発を簡単にする方法はありますか?

  • コードに飛び込むだけではいけません。人々がどのように直接コミュニケーションするかを考えてください。クライアントはメッセージを送信する人であり、サーバーは郵便局です。後でコードのロジックを翻訳します。
  • サーバーが唯一の制御下にあり、クライアントがコマンドを実行し、ロジックを実行せずに状態を表示するだけであることを確認してください。

私は、チャットがそのほんの一部である4000locマルチプレイヤーゲームを開発しました。毎日約60.000人のユーザーがプレイしています。すべてがプレーンなsocket.ioコードであり、画面を表示するためのExpress / EJSがいくつか含まれていますが、これ以上単純になるとは想像できません。特に、私からすべてのコミュニケーションを隠し、発見されて修正されるのを待っている独自のバグのセットを確実に導入する「魔法の」ライブラリを使用することによってではありません。

于 2012-09-30T00:24:33.427 に答える
0

開示:私はscoopの開発者です。

私は多かれ少なかれ同じ問題を抱えていましたが、それは多くのライブラリで解決できる通常のコールバック ピラミッドに要約されます (多数のライブラリがあります

大きな欠点を見つける前に、私はstepに非常に満足していました: それらをネストすることはできません (より多くのステップのものを呼び出すステップ呼び出し)。これは私にとって非常に重要であり、他のすべての非同期ライブラリはあまり好きではありませんでした。それらはとにかく使用しない機能を提供しすぎたためです

これは、他のすべての非同期ライブラリと同じように役立つ単純なライブラリであり、いくつかの個人的なフレーバーを備えたステップをモデルにしています。例を見てください。あなたのニーズに合うかもしれません。

于 2012-09-26T13:59:02.820 に答える
0

あなたの質問に答えるのは難しいですが、私はあなたの痛みを感じていることを保証できます... node.js がなくても、コールバックはすぐに複雑になる可能性があり、非同期テストを行うのは非常に困難です。むしろ、「うまくやるのが難しい」と言ったほうがいいと思いますが、それは、私はそれを簡単に行う方法を知っていて、知らないように聞こえるかもしれません。背景にある問題は、並行プログラミングがかつてそうであったように、非同期開発が難しいことです。

別の websocket ライブラリがあなたを助けたり、websocket を完全に回避したりするとは思いません。役立つかもしれないのは、いくつかのトリックを使用することです。上記の Andy Ray は約束を示唆しています。私はそれらを広範囲に使用していませんが、試してみる価値があります。

自己診断はあなたの味方です。JavaScript は動的言語であり、その塩分に値する型システムを持たず、null オブジェクトをマスクします。品質を保証できるのは、大量の自動テストのみです。しかし、あなたが言うように、テストは本当に難しい場合があります。

もう 1 つのトリック: アプリケーションを狂ったように計測します。計測イベントを送信し、テストでそれらを確認します。クライアントが正しいイベントを送信していることを JavaScript でチェックするヘッドレス ブラウザ (PhantomJS) に関するクールなテスト スイートを作成しました。デバッグが難しい場合がありますが、機能します。

もちろん、KISS、YAGNIなどの通常のデザインのヒントが役立ちますが、それらであなたの知性を侮辱するつもりはありません。幸運を。

于 2012-09-29T22:32:50.097 に答える
0

derby.jsも参照してください。これはmeteorに非常によく似たフレームワークですが、npm、socket.io、express などのすべての node.js の「優れた機能」に基づいて構築されています。Derby には、ブラウザー、サーバー、およびデータベース。基本的なチャットの例もあります。

Meteor は多くの独自技術 (ファイバー、独自のパッケージ マネージャー) を使用しています。流星ダービーのように、まだアルファ段階にありますが、前回は多くの魅力を獲得しました。Airbnb は最近、将来の実装のためにダービーを検討すると発表しました。

いくつかの詳細情報:

于 2012-09-27T10:21:56.137 に答える