アーランの彗星サーバー

アーランを知り始めたばかりの人々のための記事:単純な彗星サーバーの書き方。



ここに用意されているコード: 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ソケット、実稼働環境での起動などについて説明します。



All Articles