Как использовать каналы в Django?
Я пытаюсь использовать websockets в Django для создания простого сайта типа "игровая комната". Ошибка возникает после подключения сокета, все мои функции в consumer.py, кроме ws_connect, не работают (что я протестировал печатью, как показано в коде), и, как следствие, моя функция прослушивания в script.js не получает никаких данные.
Любая помощь будет принята с благодарностью... Просьба ответить, учитывая тот факт, что это моя первая встреча с веб-сокетами. Заранее спасибо:)
consumer.py -
@channel_session_user_from_http
def ws_connect(message):
message.reply_channel.send({'accept': True})
# Initialise their session
message.channel_session['rooms'] = []
print("nikhil1")
def ws_receive(message):
print("nikhil43")
payload = json.loads(message['text'])
payload['reply_channel'] = message.content['reply_channel']
Channel("chat.receive").send(payload)
print("nikhil2")
@channel_session_user
def ws_disconnect(message):
for room_id in message.channel_session.get("rooms", set()):
try:
room = Room.objects.get(pk=room_id)
room.websocket_group.discard(message.reply_channel)
except Room.DoesNotExist:
pass
print("nikhil3")
@channel_session_user
@catch_client_error
def chat_join(message):
room = get_room_or_error(message["room"], message.user)
print("nikhil4")
if NOTIFY_USERS_ON_ENTER_OR_LEAVE_ROOMS:
room.send_message(None, message.user, MSG_TYPE_ENTER)
room.websocket_group.add(message.reply_channel)
message.channel_session['rooms'] = list(set(message.channel_session['rooms']).union([room.id]))
room.size += 1
room.save()
if room.size == 2:
room.websocket_group.send(
{"text": json.dumps({"start":"yes","title":room.title,"join":str(room.id)})}
)
else:
room.websocket_group.send(
{"text": json.dumps({"start":"no","title":room.title,"join":str(room.id)})}
)
@channel_session_user
@catch_client_error
def chat_leave(message):
room = get_room_or_error(message["room"], message.user)
if NOTIFY_USERS_ON_ENTER_OR_LEAVE_ROOMS:
room.send_message(None, message.user, MSG_TYPE_LEAVE)
room.websocket_group.discard(message.reply_channel)
message.channel_session['rooms'] = list(set(message.channel_session['rooms']).difference([room.id]))
message.reply_channel.send({
"text": json.dumps({
"leave": str(room.id),
}),
})
@channel_session_user
@catch_client_error
def chat_send(message):
if int(message['room']) not in message.channel_session['rooms']:
raise ClientError("ROOM_ACCESS_DENIED")
print("nikhil5")
room = get_room_or_error(message["room"], message.user)
room.send_message(message["message"], message.user)
Script.js (частичный) -
var ws_path = '/chat/stream/';
var webSocketBridge;
function openWebSockets() {
Materialize.toast('Initializing!', 3000);
webSocketBridge = new channels.WebSocketBridge();
webSocketBridge.connect(ws_path);
console.log("Hello");
this.send = function (message, callback) {
this.waitForConnection(function () {
webSocketBridge.send(message);
if (typeof callback !== 'undefined') {
callback();
}
}, 1000);
};
this.waitForConnection = function (callback, interval) {
if (webSocketBridge.readyState === 1) {
callback();
} else {
var that = this;
// optional: implement backoff for interval here
setTimeout(function () {
that.waitForConnection(callback, interval);
}, interval);
}
};
this.send({
"command": "join",
"room": 1
})
// Handle incoming messages
webSocketBridge.listen(function(data) {
console.log(data);
if (data.error) {
Materialize.toast('Error While Connecting!', 3000);
} else if (data.message == 'Error_Closed_Group') {
Materialize.toast('You need atleast 2 people to start a Closed Match!', 3000);
} else if (data.message == 'Start_Match') {
sendNotification();
showDiv(9);
start_in_countdown(3);
fetchQuestion();
} else if (data.message == 'Question-Text') {
updateQuestion(data, 'Text');
} else if (data.message == 'Question-Img') {
updateQuestion(data, 'Image');
} else if (data.message == 'Answers') {
updateAnswers(data);
} else if (data.message == 'Psyched') {
updatePsyched(data);
} else if (data.message == 'Leaderboard') {
showLeaderboard(data);
}
});
webSocketBridge.socket.onopen = function() {
Materialize.toast('Connected!', 3000);
};
webSocketBridge.socket.onclose = function() {
Materialize.toast('Disconnected!', 3000);
};
}
routing.py-
websocket_routing = [
# Called when WebSockets connect
route("websocket.connect", ws_connect),
# Called when WebSockets get sent a data frame
route("websocket.receive", ws_receive),
# Called when WebSockets disconnect
route("websocket.disconnect", ws_disconnect),
]
custom_routing = [
# Handling different chat commands (websocket.receive is decoded and put
# onto this channel) - routed on the "command" attribute of the decoded
# message.
route("chat.receive", chat_join, command="^join$"),
route("chat.receive", chat_leave, command="^leave$"),
route("chat.receive", chat_send, command="^send$"),
]