Django と Channels (Django の新しい websocket 実装) を使用してチャット アプリケーションを作成しています。ユーザーは最初に待合室に入り、他に 3 人以上が参加すると、チャット ルームに誘導されます。コードは Chrome では問題なく動作しますが、Firefox では正しく動作しません。仕組みは次のとおりです。
- チャネル/Websocket への新しい接続時に、サーバーは少なくとも 3 人が待合室 (consumers.py) にいるかどうかを確認します。
- 少なくとも 3 人が存在する場合、グループ機能を使用して、リダイレクトするように伝えるメッセージをチャネル/Websock にブロードキャストします。
- メッセージはクライアントによって受信され、javascript でリダイレクトを実行します。
問題をデバッグするために私が取った手順は次のとおりです。
- このコードは、Firefox 以外のブラウザー (Chrome など) でも機能します。
- このコードは、待合室に到着した最初の 2 つのクライアントが Firefox で、最後の (サーバーをトリガーする) クライアントが Chrome である場合に機能します。3 つのクライアントすべてをリダイレクトします。
- 最初の 2 つのクライアントが Chrome で、最後のクライアント (サーバーをトリガーする) が Firefox の場合、Chrome クライアントはリダイレクトされますが、Firefox クライアントはリダイレクトされません。
- コードを単純な警告メッセージ (クライアントが Group ステートメントを受信したとき) に置き換えることも Firefox では機能しない (ただし、Chrome では機能する) ため、リダイレクトを実行する JavaScript に問題がある可能性は低いです。サーバーをトリガーするのがクライアントである場合、Firefox クライアントはグループ メッセージをまったく受信しないかのようです。
- チャットはチャネルを使用し、Firefox を含むすべてのブラウザーで動作します。正常に接続し、メッセージを送信し、メッセージを受信し、切断します。
これらのデバッグ手順に基づいて、Firefox がグループ リダイレクトを実行するサーバー コードを起動するときに、何か問題が発生していると思います。何がうまくいかないのかについて何か提案はありますか? 問題の特定に役立つ提案はありますか?
問題を引き起こしていると思われる consumer.py のコードは次のとおりです。
@channel_session_user_from_http
@channel_session
def wait_connect(message):
try:
wait_room, created = WaitRoom.objects.get_or_create(title=title)
except WaitRoom.DoesNotExist:
log.debug('ws room does not exist title=%s', title)
return
Group('wait-'+title, channel_layer=message.channel_layer).add(message.reply_channel)
wait_user,created = wait_room.users.get_or_create(user=message.user)
userlist = WaitUser.objects.filter(wait_room=wait_room,is_active=1)
if len(userlist)>=3:
t = {t['url']='redirecturl'}
Group('wait-'+title, channel_layer=message.channel_layer).send({'text': json.dumps(t)})
リダイレクトを実行している JavaScript コードは次のとおりです。
$(function() {
var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
var chatsock = new ReconnectingWebSocket(ws_scheme + '://' + window.location.host + window.location.pathname);
chatsock.onmessage = function(message) {
var data = JSON.parse(message.data);
window.location.replace(data.url);
};});