2017-01-25 47 views
3

私はWebリクエストのHTTPロングポーリングを実装しようとしていますが、ChannelsのドキュメントではすべてがWeb Socketsに関する適切な例を見つけることができません。私は、HTTPメッセージを消費したときに実行する必要があり何DjangoチャンネルでHTTPロングポーリングを行う方法

はどちらかである:(おそらく信号を使用して)特定のモデルを保存するときに送信されますグループでのメッセージの

  • 待機
  • 待ちのためにメッセージが受信されない場合はタイムアウトになります。

クライアントに何かを返します。だから私は、私は今のところ、送信するためには何もないことを示します。このhttp_consumerで何かを返すために持っているが、私ができる

def http_consumer(message): 
    # Make standard HTTP response - access ASGI path attribute directly 
    response = HttpResponse("Hello world! You asked for %s" % message.content['path']) 
    # Encode that response into message format (ASGI) 
    for chunk in AsgiHandler.encode_response(response): 
     message.reply_channel.send(chunk) 

今私は例で見ることができるコードを持っていますここでブロックしてください。多分私は何も返すことができないでしょうか?そして、特定のグループの新しいメッセージをキャッチするか、タイムアウトに達してクライアントに応答を送信する必要があります。

私が私が後で応答できるようにどこかmessage.reply_channelを保存する必要がありますが、私がどのようにと途方に暮れてるようです:

  • キャッチグループメッセージとは、応答を生成
  • メッセージが受信されなかったとき(タイムアウト)に応答を生成します。おそらく遅延サーバはここで動作しますか?

答えて

0

ですから、私がこれをやったやり方は以下の通りです。

私がすぐに返信することができない場合は、message.reply_channelをグループに保存して、関連するイベントの場合に通知を受け、遅延メッセージをスケジュールします待機する最大時間に達しました。

group_name = group_name_from_mac(mac_address) 
Group(group_name).add(message.reply_channel) 
message.channel_session['will_wait'] = True 

delayed_message = { 
    'channel': 'long_polling_terminator', 
    'content': {'mac_address': mac_address, 
       'reply_channel': message.reply_channel.name, 
       'group_name': group_name}, 
    'delay': settings.LONG_POLLING_TIMEOUT 
} 
Channel('asgi.delay').send(delayed_message, immediately=True) 

次に、2つのことが起こります。関連するグループにメッセージを受け取り、応答が早期に送信されるか、または遅延メッセージが到着して、私たちが待たなければならなかったことを通知し、イベントがないことを示す応答を返す必要があります。関連するイベントは、私はDjangoの信号に頼ってる発生したときにメッセージをトリガするために

タイムアウトの期限が切れる
class PortalConfig(AppConfig): 
    name = 'portal' 

    def ready(self): 
     from .models import STBMessage 

     post_save.connect(notify_new_message, sender=STBMessage) 

def notify_new_message(sender, **kwargs): 
    mac_address = kwargs['instance'].set_top_box.id 
    layer = channel_layers['default'] 
    group_name = group_name_from_mac(mac_address) 
    response = JsonResponse({'error': False, 'new_events': True}) 
    group = Group(group_name) 
    for chunk in AsgiHandler.encode_response(response): 
     group.send(chunk) 

、私はlong_polling_terminatorチャネル上でメッセージを取得し、私がメッセージを送信する必要がありますそれはイベントがないことを示しています行うには

def long_polling_terminator(message): 
    reply_channel = Channel(message['reply_channel']) 
    group_name = message['group_name'] 
    mac_address = message['mac_address'] 
    layer = channel_layers['default'] 
    boxes = layer.group_channels(group_name) 
    if message['reply_channel'] in boxes: 
     response = JsonResponse({'error': False, 'new_events': False}) 
     write_http_response(response, reply_channel) 
     return 

最後の事はグループからこのreply_channelを削除し、私はhttp.disconnect消費者にこれを行うです:

def process_disconnect(message, group_name_from_mac): 
    if message.channel_session.get('will_wait', False): 
     reply_channel = Channel(message['reply_channel']) 
     mac_address = message.channel_session['mac_address'] 
     group_name = group_name_from_mac(mac_address) 
     Group(group_name).discard(reply_channel) 
関連する問題