我完全迷住了,我花了几个小时研究导致此错误的原因。我使用以下教程(https://channels.readthedocs.io/en/latest/tutorial/part_1.html)来了解Django通道,以在当前项目中交换ajax短轮询。
我已将所有内容都插入到我的项目中,除了websocket断开连接之外,它应该可以正常运行。浏览器显示WebSocket connection to 'ws://localhost:8001/ws/members/vote/2/' failed: Error during WebSocket handshake: Unexpected response code: 500
。
端子输出:
2019-12-02 19:44:23,543 ERROR Exception inside application: 'room_name'
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/channels/sessions.py", line 183, in __call__
return await self.inner(receive, self.send)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/channels/middleware.py", line 41, in coroutine_call
await inner_instance(receive, send)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/channels/consumer.py", line 59, in __call__
[receive, self.channel_receive], self.dispatch
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/channels/utils.py", line 51, in await_many_dispatch
await dispatch(result)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/asgiref/sync.py", line 244, in __call__
return await asyncio.wait_for(future, timeout=None)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/tasks.py", line 339, in wait_for
return (yield from fut)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/channels/db.py", line 14, in thread_handler
return super().thread_handler(loop, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/asgiref/sync.py", line 277, in thread_handler
return func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/channels/consumer.py", line 105, in dispatch
handler(message)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/channels/generic/websocket.py", line 39, in websocket_connect
self.connect()
File "./vote/consumers.py", line 10, in connect
self.room_name = self.scope['url_route']['kwargs']['room_name']
'room_name'
127.0.0.1:54775 - - [02/Dec/2019:19:44:23] "WSDISCONNECT /ws/members/vote/2/" - -
这是我的代码段
Vote.html
<script>
var questionID = {{ question_id_json }};
var chatSocket = new WebSocket(
'ws://' + window.location.host +
'/ws/members/vote/' + questionID + '/');
chatSocket.onmessage = function(e) {
var data = JSON.parse(e.data);
console.log(data);
var vote = data['vote'];
var allvotes = data['allvotes'];
console.log(allvotes);
drawChart(allvotes);
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-submit').onclick = function(e) {
var voteInputDom = document.querySelector('#vote-input');
var vote = voteInputDom.value;
chatSocket.send(JSON.stringify({
'vote': vote
}));
};
</script>
投票/路由.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'^ws/members/vote/(?P<question_id>\d+)/$', consumers.ChatConsumer),
]
Vote / consumers.py
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
from django.db.models import Count
from .models import Vote
import json
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'vote_%s' % self.room_name
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
# Leave room group
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
vote = text_data_json['vote']
print(vote)
save_question = Vote(value=vote)
save_question.save()
votes = Vote.objects.values('value').order_by('value').annotate(count=Count('value'))
allvotes = []
for x in range(1, 10):
trigger = False
for vote_item in votes:
if int(vote_item['value']) == x:
allvotes.append(vote_item['count'])
trigger = True
break
if trigger is False:
allvotes.append(0)
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'chat_message',
'vote': vote,
'allvotes': allvotes
}
)
# Receive message from room group
def chat_message(self, event):
vote = event['vote']
allvotes = event['allvotes']
# Send message to WebSocket
self.send(text_data=json.dumps({
'vote': vote,
'allvotes': allvotes,
}))
我在Setting.py中设置了Redis
ASGI_APPLICATION = "pullingapp.routing.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
如果您能帮助我,我将不胜感激
答案 0 :(得分:0)
@ ken4scholars帮助我指出了正确的方向。 websocket连接函数的kwarg'room_name'错误,而不是websocket_urlpatterns中的'question_id'。
答案 1 :(得分:0)
只需提出我的评论即可。 stacktrace显示您正在尝试获取不存在的URL kwarg room_name
。在您的vote/routing.py
中,只有question_id
个网址kwarg存在,因此很可能就是您想要的