ですから、私がこれをやったやり方は以下の通りです。
私がすぐに返信することができない場合は、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)