ここに用意されているコード: github.com/maxlapshin/comet
説明
コメットサーバーは、カウボーイ、tinymq、およびジャバスクリプトを使用して記述されます。
コードはタグ付きでgithubに投稿されます。 メインステージにはタグが付けられています。ロールバックして、ある時点で正確に何が行われたかを確認できます。
記事自体はコードと並行して書かれていますが、これはgitaの歴史から明らかです。
ロジックは次のとおりです。http経由でサーバーにメッセージを送信すると、メッセージキューに落ち、そこからクライアントがロングポールリクエストを介してスクープします。
Erlangはここで2つの点で優れています。
1)メッセージをメモリに保持する機能
2)数百万(!)の未回答のリクエスト、つまり クライアントが立って、答えを待っている場合、サーバーは少し後で答えます。
始めるための雑貨
まず、すべてのルーチンが必要です:鉄筋、依存関係。
mkdir comet cd comet git init wget https://github.com/basho/rebar/wiki/rebar chmod +x rebar
次に、rebar.configを作成して依存関係をインストールします。
{lib_dirs, ["apps", "deps"]}. {sub_dirs, [ "apps/comet" ]}. {erl_opts, [ debug_info, warn_format, warn_export_vars, warn_obsolete_guard, warn_bif_clash ]}. {deps, [ {cowboy, "0.6.*", {git, "git://github.com/extend/cowboy.git", {tag, "0.6.1"}}}, {tinymq, ".*", {git, "git://github.com/evanmiller/tinymq.git", "386813add4"}} ]}.
tinymqでの記事の執筆中に、APIに変更が加えられました。 特定のコミットをロックすることをお勧めします!
そして依存関係を引き出します:
./rebar get-deps
Emakefileをすぐに作成します。 多くの人がemakeの使用を拒否していますが、なぜそうするのかは後でわかりません。
{"apps/comet/src/*", [debug_info, {outdir, "apps/comet/ebin"}, {i, "apps/comet/src"}]}. {"deps/cowboy/src/*", [debug_info, {outdir, "deps/cowboy/ebin"}, {i, "deps/cowboy/src"}]}. {"deps/tinymq/src/*", [debug_info, {outdir, "deps/tinymq/ebin"}, {i, "deps/tinymq/src"}]}.
アプリケーションのバックボーンを作成することは今でも残っており、すべて問題ありません。
mkdir -p apps/comet cd apps/comet ../../rebar create-app appid=comet cd -
depsとebinを.gitignoreに追加し、何が起こったかをコンパイルします。
./rebar compile
瞬間はv1とタグ付けされます。
打ち上げ
アーランでアプリケーションを実行する方法に関しては、混乱と動揺があります。 インフラストラクチャを正確に起動する方法の意味で。
私は通常、以下を指定する実行ルールを使用して開発用のMakefileを実行します。
ERL_LIBS=apps:deps erl +K true -name comet@127.0.0.1 -boot start_sasl -s comet_app -sasl errlog_type error
次のことを理解することが重要です。Erlangには体制の開発と生産はありません。 多くのフレームワークがだましているこのすべてのビリヤードはありません。
オプションについて詳しく説明します。
ERL_LIBS=apps:deps
は、ライブラリを検索するようにErlangディレクトリに指示します。 ライブラリは、ebinを含むディレクトリです。
+K true
は、epoll / kqueueを使用できることを示します
-name comet@127.0.0.1
明示的なホストを持つ長い名前
-boot start_sasl
覚えて、繰り返します
-s comet_app
-comet_appモジュールからstart / 0関数を実行します(現時点ではまだありません)
-sasl errlog_type error
により、すべてが正常であるという不要なメッセージから
-sasl errlog_type error
を削除できます。
ここで、すべてを開始するには、comet_app.erlにstart / 0関数を追加する必要があります。
-export([start/0]). start() -> application:start(comet).
その後、すべてをコンパイルします。
> ./rebar compile > make run ERL_LIBS=apps:deps erl +K true -name comet@127.0.0.1 -boot start_sasl -s comet_app -sasl errlog_type error Erlang R15B (erts-5.9) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:true] Eshell V5.9 (abort with ^G) (comet@127.0.0.1)1>
つまり 空のアプリケーションが開始されました。 終了Ctrl + cまたはhalt()。 コンソールで。
V2タグ
Webサーバーの起動
インフラストラクチャは完成しました。Webサーバーの起動に移りましょう。
アプリケーションの開始から、いくつかのハンドラーでカウボーイを開始しますが、このためには、静的ファイルを正しくレンダリングするために、最初に別のmimetypesアプリケーション(https://github.com/spawngrid/mimetypes)を追加する必要があります。
行
{mimetypes, ".*", {git, "git://github.com/spawngrid/mimetypes.git"}}
をrebar.configに追加して引き出します:
./rebar get-deps
comet_app.erlに必要なコードを書き、最小コードをwww / index.htmlに追加して実行します。
実行してローカルホストに移動します:8080 /
タグv3
メッセージをキューに書き込む
url / sendmessageにjquery、form、および個別のsendmessage_handlerハンドラーを追加します
モジュール自体は、カウボーイの指示に従って明確に書かれています。
カウボーイの場合、非常に重要なことを1つ覚えておくことが重要です。カウボーイAPIのすべての関数は、応答と新しい状態を返します。 これは、要求に応じてすべてのデータを解析するために行われます。
常に新しい状態を使用することが重要です。そうしないと、クールダウンする可能性があります。
ここで、Emakefileを使用する理由を説明することが重要です。 開発中のコードの再コーディング方法にはさまざまなアプローチがあります。 通常の
make:all([load]).
だけが好き
make:all([load]).
他のオプションはリローダーまたは同期です。 それらはすべて、悪魔をいつ、どのような地獄でコーディングするという点で悪いです。 sslに問題があるため、同期は簡単にクラストできます。 作業make:all([load])用です。 (このコマンドはerlangコンソールで実行する必要があります)、Emakefileを実行しました
次に、メッセージキューをオンにします。 comet_supアプリケーションのスーパーバイザーに追加します。
コメットロジックを直接追加できるようになりました。
{Post, Req2} = cowboy_http_req:body_qs(Req), {<<"body">>, Body} = lists:keyfind(<<"body">>, 1, Post), tinymq:push(<<"default_channel">>, Body),
V4タグ
キューからメッセージを引く
彗星では次のような状況が考えられます。
1)来て、すでにキューにメッセージがあります
2)到着しましたが、メッセージはありません。表示されるのを待っています。
すでにメッセージを見たことを理解するには、ソート可能な識別子を使用する必要があります。 私たちの場合、最も信頼できるのはリアルタイムです。 これは、tinymqの機能とまったく同じです。
comet_handlerを追加します。これは、特別なカウボーイチップを使用して彗星を実装します。
正確に何が起こっているのかを詳しく見てみましょう。
1)クライアントが/最後のタイムスタンプを持っているか持っていないか、彗星に来る
2)ハンドラーはtinymqでチェックします:このタイムスタンプより新しいメッセージがあるかどうかをポーリングします。
3)存在する場合、ハンドル/ 2を介して単純なメカニズムで応答します
4)そのようなメッセージがない場合、tinymqを介してメッセージ配信にサブスクライブします:プル/ループ/ 3サイクルでハングします
5)目的のメッセージが到着したら、JSONにパックし、新しいタイムスタンプと一緒にクライアントに送信します
jsonでパッケージ化するためのmochijson2モジュールを追加しました
V5タグ
このためにHTMLを添付するだけです。
CometのHTML
すべてが同じことを行っている多くのニュアンスがあります:あまりにも頻繁な要求でサーバーをダンプしない方法。 つまり 緊急切断後、少し待ってください。 ただし、これらはすべて後から、最初に彗星を購読するために残しておきます。
V6タグ
次は?
そのため、ドラフトでは、動作する彗星の最小限の例が用意されています。 このフォームでは、本番では実行できません。終了する必要があります。
1)認可
2)チャンネル表示
その後、ここで説明するコードを実稼働環境にロールアウトできます。 はい、アーランは良いです。なぜなら、原則として、プロトタイプを戦闘に投入できるからです。
また、次の記事では、Webソケット、実稼働環境での起動などについて説明します。