これまでのところ、我々は、通信のためのHTTPプロトコルに基づいており、内部のプロジェクトに連絡したします。httpリンクプロトコルはステートレスである、クライアントが要求を送信し、サーバは応答を返し、サーバが自動的にクライアントに向けてメッセージを送信しません。
積極的にクライアントにメッセージをプッシュサーバーを達成するための3つの方法があります。
1 。ポーリング 2 。ロングポーリング 3.websocket
投票
低効率、基本的な必要性
ましょうブラウザは、例えば、5秒ごとに、そしてあなたのデータは5秒まで遅れることが要求送信バックエンド(密かにAJAXによるバックエンドにデータを送信する)に向けてタイミング要求を送信
欠点
データが遅延が
過度のリソースを消費します
あまりにも多くの時間を要求
ロングポーリング
互換性は、一般的な大企業がそれを使用することを検討します
#キュー+ AJAX 各クライアントにサーバがそのキューを取得するには、データの方にAJAXを介してサーバにブラウザを許可する、待ち行列を確立するために、 そこにはデータがブロックされませんですが、そのようなあなたの30秒をブロックとして、ブロックされなかったであろう場合にも、データは返され、その後、クライアントのブラウザが再びデータを要求するリクエストを送信してみましょう。 サーバーへのデータを取得密かに内部ブラウザましょう、クライアントは最初にユニークなキューを作成するために、各クライアントを与える来て、結局、自身の対応するキューからクライアント要求データを要求し、
そしてキューデータがないときに我々は基本的にゼロ遅延を行うにはトラップ引数の追加例外タイムアウトパターンを使用して、メソッドのブロックがすぐにデータ一度に実行されます取得
ポーリングに関して 、基本的に何のメッセージ遅延 要求の数が数を削減しないように #のウェブをそして、QQのマイクロチャネルバージョンは、実質的論理例えばAで使用されています
実装のAjaxベースのポーリング機能と長い行列(チャットルームのジャンゴ簡易版)
「」 " 1.ホームカスタムユーザー独自の表現では、各ユーザーが開始キュー バックエンドへのバインドデータ2.送信ボタンクリックイベントは、各キュー伝える 3.書き込みコードデータが自動的にAJAXサイクルコール得る 4。ページをレンダリングするためのフロントエンドデータ収集DOM操作 。「」 "
urls.py
#ベースAJAX +長いポーリング・キューの実装、チャットページ URL(R&LT ' ^ ab_bl / ' 、views.ab_bl)、 #1 の送信情報の後端にフロントエンド URL(R&LT ' ^ send_msg / ' 、views.send_msg)、 #は、フロントエンドを示します情報 URL(R&LT ' ^ get_msg / '、views.get_msg)
ab_bl.html
<BODY> <H1の> {{名前}} IM </ H1の> <P> の<input type = " テキスト"名前= " コンテンツ" ID = " D2 " > <ボタンID = " D1 " >送信</ボタン> </ P> <H1の>チャット</ H1>の <DIV ID = " コンテンツ" > </ div> <SCRIPT> // 送信トリガアヤックスクリック $(' #D1 ' ).clickを(関数(){ $アヤックス({ URL:"/ send_msg / "、// メッセージングアドレス、後端 タイプ:' POST ' 、 データ:{ ' コンテンツ':$(' #D2 ').val()} // バックエンドに渡される情報 成功:機能(データ){ // 返信メッセージの前端に後端 } }) }); 機能GETMSG(){ $アヤックス({ URL:' / get_msg / ' 、 タイプ:' GET ' 、 データ:{ ' 名前':' {{名前}} ' } // たびに現在ログインらデータキュー 成功:関数(引数){ //は、対応するメッセージを処理するために返さない IF (args.statusを){ // ニュースページがグローバル内部のトークメッセージチャットの記録にレンダリングされる @ 1は、ラベル作成 VAR PELEを = $(" <P> ' ); // 2 ラベルテキストには、提供され 、pEle.text(args.msg) 。// 3は、ラベルチャットに作成したラベルは、DIV話す $(' #contentを" ).append(PELE) } 他は{ // メッセージは送信し続けない } GETMSG() // サイクル要求データ } }) } $(関数(){ GETMSG() // ページが自動的に実行されるロード }) </ SCRIPT> </ BODY>
views.py
django.shortcuts インポート、レンダリングのHttpResponse インポートキュー から django.utils.httpwrappers インポートjsonResponse #グローバル辞書の q_dict = {} #:{キュー、....「ユニークを表す」} DEF ab_bl(要求): #通過パラメーターパス名から識別作るために、ユーザーごとに 名前= request.GET.get(「名前」) #キューを作成するために、各クライアントへの q_dictを[名前] = Queue.Queue()が 返すレンダリング(リクエスト、「ab_bl.htmlを」、地元の約()) #の送信されたメッセージの後端部にフロントエンド DEF send_msg(要求): IFは == request.method 「POSTを」: #取得ユーザーによって送信されたメッセージ:Ajaxのデータをデータ転送に コンテンツ= request.POST.get(「コンテンツ」) #は、すべてのキューにメッセージを渡す ために Q にq_dict.values (): q.put(コンテンツ) を返すのHttpResponse(' OK ' ) #は、データキュー取得 DEF :get_msg(リクエスト) 名 = request.GET.get(' 名前' ) #GETキューに対応する Q = q_dict.get (名) #いくつかの応力が削除されたデータキューとブラウザのフロントエンドに戻すことができる #と辞書の定義Ajaxの相互作用 {back_dic = 「ステータス」:真、「MSG 」:「」} 試し: データ = q.get(タイムアウト= 10) #など10sが直接与えられていない [back_dic ' MSG ' ] = データ 以外queue.Empty AS E: back_dic [ ' ステータス' ] = Falseの リターン jsonResponse(back_dic)
WebSocketを
現在主流のブラウザは、WebSocketをサポートしています
HTTPプロトコルのネットワークプロトコル(非暗号化送信)
HTTPSプロトコルネットワークプロトコル(暗号化通信)
2契約以上が短いリンクされている
のWebSocketのネットワークプロトコル(暗号化通信)
ブラウザとサーバは、もはやデフォルトでリンクを作成して切断した後
、両端をに基づいて行うことができますメッセージの送信および受信するためのリンク
出産用WebSocketは本当にサーバーはメッセージではなく、受動的な伝送を送ることができます
WebSocketの内部原則
二つの部分に分かれて 1 。ハンドシェイクリンク:サーバーがサポートする契約のWebSocketていることを確認し 、自分自身を残して、サーバへのアクセス(HTTPベースのプロトコル)ブラウザがサーバにコピーを送信するリクエストヘッダ内のランダムな文字列を生成する第1の時間のためにパーツ 秒 -WebSocketキー:ePW8kp1XqLNWbJxE / == Q38SAの サーバーとの以下のランダムな文字列をやってクライアント ランダム文字列 + マジック文字列スプライス およびスプライシングされた繰り返し暗号化された結果(SHA1 / Base64での)へ暗号文
サーバがクライアントブラウザに再びレスポンスヘッダを経由して送信された暗号文を生成します、 サービス側のサポート用WebSocketの一貫した記述場合はブラウザが自動的に、農産物暗号文の当事者よりも一貫している 、彼らは与えられていない場合 に比べて仮定ビルド用WebSocketをメッセージ送受信するリンクに基づいて、リンク 2 。データ受信 暗号文で送信を >>> 必然的に復号化(GHS)プロセス伴う ネットワーク上で送信されたデータに基づいて、バイト単位で我々のpythonにバイナリ形式対応しているの一種である データの復号処理 1 。7メッセージを受信した後、2バイト目のデータ(ペイロード)を読み取るためには、バイト データ7のサイズに応じて異なる復号処理を指定する = 127 以降の8つのワードを読み出し:セクション = 126 :2つのバイトは、後で読み取る <= 125 :リードバックしない 以前に読み出され、除去され、その後、さらに4バイト(マスキング読み出されたデータに - Key)を 解析するために戻ってそれを保持(式に基づいて)実データ
コードの検証
バックエンドのコード行のフロントエンドを把握する必要はありません。
<! -単一のコード行を記述するだけで、遠位- > <SCRIPT> のvar WS =新しい新しいA用WebSocket(' WS://127.0.0.1:22です/ ' ) </ SCRIPT> < - WSによる目標ポイント!データ交換用WebSocketを達成するための方法を送ります- >