XMPPは吸う

チャットなしのソーシャルアプリケーションを開発し、2週間で開発しました。IMを実装するための既存のプロトコルに関する知識はまったくありませんでした。 それは足で自分を撃つために必要なキットではなかったが、その過程で起こった。 数回。



-パシャ、チャットをする必要があります。

-はい、すべてがシンプルです。ここの私の友人は、アプリケーションでチャットにXMPPを使用しました。



私たちの要件は何でしたか? グループ会話なしの、ユーザー間の特別なシンプルなメッセージングは​​ありません。 プラットフォーム:Web(Webソケットを介した作業をサポート)、Android、iOS。 ユーザーの作成は、サーバーアプリケーションによってのみ自動的に行われる必要があります。 もちろん、メッセージが読まれたかどうかについてメモをとって(アプリケーションがさまざまなデバイスから使用できると想定されている)、チャットログを表示できると便利です。 一般に、2015年のインスタントメッセージングの標準機能。 サーバーが水平方向に拡張できる場合、ボーナスポイントが付与されます。



うーん、それは魅力的ですね。 Googleと他の標準との比較、 Wikipediaの記事へのリンクを開きます。 最初に考えたのは、すごい、かっこいい、必要なものはすべてあるということです。



なぜXMPPを選択したのですか?





プロトコル



プロトコルを開発した人たちは本当に多くを提供しました。 たとえば、メッセージアーカイブの設計を見てみましょう。 セッションの個別のアーカイブ設定。 ユーザーの1人がメッセージをサーバーに保存しないことを望み、2人目がこれを望んでいる場合の対処方法の説明。 同時に、ページごとにメッセージのアーカイブを受信するための通常のメカニズムはありません。 通常、オフセットと制限を設定することを意味します。 ここでは、メッセージの最大数を設定するmaxパラメーターと、メッセージを受信する時間を意味するstartパラメーターのみを設定できます。



または、たとえば、プロトコルは、オフラインメッセージ(ユーザーにオフラインで送信されるメッセージ)で何をすべきかを決定しません。 したがって、ほとんどのサーバーは、次のログイン時にそれらを単にユーザーに送信します。 ユーザーが複数のデバイスからアプリケーションを使用できるという要件を覚えていますか? そのため、スマートフォンでアプリケーションを実行してからWebアプリケーションを入力すると、すべてのオフラインメッセージがスマートフォンに届き、それだけです。 つまり、Webアプリケーションではこれについて知ることができません。 一部のサーバーの動作が異なる、つまりXEP-0013を実装していることに注意してください。



そうそう、2015年のIM(インスタントメッセージング)のプロトコルには、未読メッセージのリストを取得し、それらの一部を既読としてマークできる仕様がありません。 絶対に。



実装



最初の段階では、前の段落でどのような問題が発生するのかわからなかったため、MongooseIMがサーバー実装として選択されました。 特定のIPからのみ登録を禁止できるスケーラブルなWebsocketをサポートしています。 JSJaCライブラリは、strophe.jsよりも便利なAPIを提供するため、Webフロントエンドに選択されました。 ハーフキックでサーバーに接続されたJSJaCの例からの簡単なページと私の喜びは際限がありませんでした。 作業は終了したようです。 まあ、ほとんど。



そして、前の段落で最後に発声された問題に遭遇しました。 プロトコルは未読メッセージを受信する可能性を暗示しておらず、メッセージが既読/未読であることをまったく意味しないため、機能のこの部分を追加する必要があります。 アーランプログラミングが苦手なので、他の適切なサーバー実装を探し始めました。 JavaまたはJavaScriptでの実装を探していました。



Openfireは、JavaでのXMPPの最も一般的な実装の1つです。 プラスはセットアップの容易さを含みます:すべてはウェブインターフェースを通して起こります。 さらにマイナスのみ:リソースの厳格さ、Webソケットを介した作業のためのプラグインの欠如。



JavaScriptプロジェクトから言及する価値がある唯一のものはxmpp-ftwでした。 このプロジェクトは、XMPPからの多くの拡張機能を実装しています。 ただし、既存のクライアントライブラリを使用できないため、その使用を中止する必要がありました。 おそらく、すべてが彼にとってそれほど良くないだろう。



ティガセは最初は救いのようでした。 Javaの高速でスケーラブルなサーバー。プラグインを作成し、プラグインを簡単に実行できます。 そして、ドキュメントの欠如。 代わりに、ソースコードを読むことをお勧めします。 しかし、それは何でもありません、私はそれを最も頻繁にしています。 新しいメッセージを未読としてマークするプラグインを書きました。 管理APIを正常に使用できなかったため、ユーザーを登録するためにデータベースに直接書き込む必要がありました。 幸いなことに、TigaseにはMongodbに接続するためのドライバーがあります。 未読メッセージの受信は、アプリケーションのAPIの別のメソッドを使用して行われました(松葉杖、Tigase内でプラグインにすることもできますが、Tigase内のDBMSと通信するためにかなり低レベルのAPIが使用されるため、かなり時間がかかります) すべてを接続して確認しました-メッセージが既読としてマークされるまで(ところで、メッセージはxmppでidを持たないため、特定のユーザーとのすべての通信を既読としてマークすることにしました)、未読リストに返されます。 すべてが機能します。 オフラインメッセージのあるケースのみをチェックすることは残ります。 はい、オフラインメッセージを処理するプラグインはアーカイブよりも早く起動するため、未読としてマークされていません。 Tigaseフォーラムで、開発者は、私が必要とする動作が商用Tigase Unified Archiveプロジェクトに実装されていると答えました。 名前によるグーグルは何にもつながりませんでした、フォーラムの開発者は、プロジェクトはまだ不安定であり、リリースバージョンがないと述べました。 サーバーのソースを調べてみると、すべてのメッセージをチャットに設定することで正しい動作が得られることがわかりました。



それでは、顧客の実装を見ていきましょう。 JavaScriptの実装から始めましょう。 JSJaCのみを試しましたが、最終的にはstrophe.jsに変更されました。 最初のAPIはより快適なAPIを備えていますが、基本機能のみを備えており、たとえばアーカイブなどの拡張機能をサポートしていません。 同時に、stropheは代わりにかなり便利なxmlビルダーを提供します。 さて、XMPPの内部からの抽象は機能しませんでした。 ところで、JSJaCのWebソケットコネクタはWebkitでのみ機能します。



Javaクライアントの中で、現時点ではSmackのみが試されています。 無効なパケットを送信すると、NoResponseExceptionがスローされる可能性が高くなります。それだけです。



おわりに



たぶん私の問題は、誰かが私の問題のいくつかを私のために解決し、うまくやることを望んでいたことです。 最初にこれをすべて知っていれば、自分のチャットサーバーを作成することをお勧めします。 真剣に。 プロトコルが悪いとか、現代の要件でIMを実装するのに適していないということではありませんが、私はまだそう思っています。 他の多くの人々のコードと仕様をシャベルで掘るよりも、自分のコードを持ち、拡張に必要な機会を与えたいと思っていました。 XMPPは、おそらく適切であると思われる広範なタスクを解決するために非常にうまく使用されています。 ほとんどのソリューションは基本的な機能のみを使用しますが。



All Articles