python - 消息类型 websocket.group_send 没有处理程序,如何解决?
问题描述
我从一个用户的 websocket 连接切换到聊天室,两个人可以相互连接,但是在切换时,在接收方法中,现在需要 group_send,然后它停止工作,如何解决?
完整回溯
> Exception inside application: No handler for message type
> websocket.group_send File
> "D:\Dev\Web\Chaty\lib\site-packages\channels\sessions.py", line 183,
> in __call__
> return await self.inner(receive, self.send) File "D:\Dev\Web\Chaty\lib\site-packages\channels\middleware.py", line 41,
> in coroutine_call
> await inner_instance(receive, send) File "D:\Dev\Web\Chaty\lib\site-packages\channels\consumer.py", line 59, in
> __call__
> [receive, self.channel_receive], self.dispatch File "D:\Dev\Web\Chaty\lib\site-packages\channels\utils.py", line 52, in
> await_many_dispatch
> await dispatch(result) File "D:\Dev\Web\Chaty\lib\site-packages\channels\consumer.py", line 75, in
> dispatch
> raise ValueError("No handler for message type %s" % message["type"]) No handler for message type websocket.group_send
> WebSocket DISCONNECT /messages/dildo/ [127.0.0.1:58910]
消费者
import asyncio
import json
from django.contrib.auth import get_user_model
from channels.consumer import AsyncConsumer
from channels.db import database_sync_to_async
from .models import Thread, ChatMessage
class ChatConsumer(AsyncConsumer):
async def websocket_connect(self, event):
print('Connected', event)
other_user = self.scope['url_route']['kwargs']['username']
me = self.scope['user']
thread_obj = await self.get_thread(me, other_user)
chat_room = f"thread_{thread_obj.id}"
self.chat_room = chat_room
await self.channel_layer.group_add(
chat_room,
self.channel_name
)
await self.send({
'type':'websocket.accept'
})
async def websocket_receive(self, event):
print('Recive', event)
front_response = event.get('text', None)
if front_response is not None:
compiled_response_data = json.loads(front_response)
if 'FormData' in compiled_response_data:
pass
author = str(self.scope['user'])
Response_ = {
'Message': compiled_response_data['FormData']['message'],
'Author': author
}
new_event = {
'type':'websocket.send',
'text': json.dumps(Response_)
}
print(new_event)
await self.channel_layer.group_send(
self.chat_room,
new_event
)
async def websocket_disconnect(self, event):
print('Disconnected', event)
@database_sync_to_async
def get_thread(self, user, other_username):
return Thread.objects.get_or_new(user, other_username)[0]
我的 html 模板
{% extends "base.html" %}
{% block content %}
<h3>Thread for {% if user != object.first %}{{ object.first }}{% else %}{{ object.second }}{% endif %}</h3>
<ul id='chat-items'>
{% for chat in object.chatmessage_set.all %}
<li>{{ chat.message }} via {{ chat.user }}</li>
{% endfor %}
</ul>
<form id='form' method='POST'> {% csrf_token %}
{{form }}
<input type="text" name='porn'>
<input type="text" name='pov'>
<button type='submit' class='btn btn-primary'>Submit</button>
</form>
{% endblock %}
{% block script %}
<script>
const from_user = '{{ object.first }}',
to_user = '{{ object.second }}';
// websocket scripts
let loc = window.location,
path_first_part = 'ws://',
path_second_part = loc.host + loc.pathname,
endpoint = '',
FormItself = $('#form'),
FormData = $('#form input'),
DataHolder = {},
ChatItself = $("#chat-items");
if (loc.protocol == 'https:'){
path_first_part = 'wss://'
}else{
path_first_part = 'ws://'
}
endpoint = path_first_part + path_second_part
let socket = new WebSocket(endpoint);
socket.onmessage = function(e){
console.log('Message', e);
let parset_data = JSON.parse(e.data),
Chat_MSG = parset_data.Message,
Chat_AUTHOR = parset_data.Author;
ChatItself.append('<li>' + Chat_MSG + ' <= via => ' + Chat_AUTHOR + '</li>');
};
socket.onopen = function(e){
console.log('Open', e)
FormItself.submit(function(event){
event.preventDefault();
DataHolder['FormData'] = {};
FormData.each(function(key, value){
DataHolder['FormData'][value.name] = value.value;
value.value = '';
})
socket.send(JSON.stringify(DataHolder));
})
console.log(DataHolder)
};
socket.onerror = function(e){
console.log('Error', e)
};
socket.onclose = function(e){
console.log('Close', e)
};
</script>
{% endblock %}
看起来您的帖子主要是代码;请添加更多细节。
解决方案
兄弟,很高兴能帮到你,我自己一创建组就遇到了,然后你需要给组发消息,也就是type: 'websocket.send'
在
websocket_receive中你需要放一个回调函数,然后你已经可以使用向 websocket 发送消息了。
new_event = {
'type':'chat_message',
'text': json.dumps(Response_)
}
接下来创建 chat_message 回调函数
async def chat_message(self, event):
print('\n',event)
front_response = event.get('text', None)
if front_response is not None:
compiled_response_data = json.loads(front_response)
Response_ = {
'Message': compiled_response_data['Message'],
'Author': compiled_response_data['Author']
}
# Send message to WebSocket
await self.send({
'type':'websocket.send',
'text': json.dumps(Response_)
})
所以最后你的消费者会是这样的。
import asyncio
import json
from django.contrib.auth import get_user_model
from channels.consumer import AsyncConsumer
from channels.db import database_sync_to_async
from .models import Thread, ChatMessage
class ChatConsumer(AsyncConsumer):
async def websocket_connect(self, event):
print('Connected', event)
other_user = self.scope['url_route']['kwargs']['username']
me = self.scope['user']
thread_obj = await self.get_thread(me, other_user)
chat_room = f"thread_{thread_obj.id}"
self.chat_room = chat_room
await self.channel_layer.group_add(
chat_room,
self.channel_name
)
await self.send({
'type':'websocket.accept'
})
async def websocket_receive(self, event):
print('Recive', event)
front_response = event.get('text', None)
if front_response is not None:
compiled_response_data = json.loads(front_response)
if 'FormData' in compiled_response_data:
pass
author = str(self.scope['user'])
Response_ = {
'Message': compiled_response_data['FormData']['message'],
'Author': author
}
new_event = {
'type':'chat_message',
'text': json.dumps(Response_)
}
await self.channel_layer.group_send(
self.chat_room,
new_event
)
async def websocket_disconnect(self, event):
print('Disconnected', event)
# Receive message from room group
async def chat_message(self, event):
print('\n',event)
front_response = event.get('text', None)
if front_response is not None:
compiled_response_data = json.loads(front_response)
author = str(self.scope['user'])
Response_ = {
'Message': compiled_response_data['Message'],
'Author': author
}
message = event['text']
# Send message to WebSocket
await self.send({
'type':'websocket.send',
'text': json.dumps(Response_)
})
@database_sync_to_async
def get_thread(self, user, other_username):
return Thread.objects.get_or_new(user, other_username)[0]
#saving to db
@database_sync_to_async
def create_chat_message(self, author, msg):
thread_obj = self.thread_obj
return ChatMessage.objects.create(thread=thread_obj, user=author, message=msg)
推荐阅读
- sql - Oracle Query 基于数据到横向
- python - 如果数字是偶数,则对奇数进行平方和对数字 1 进行平方
- android - 我得到:java.lang.SecurityException:“gps”位置提供者需要 ACCESS_FINE_LOCATION 权限
- javascript - jQuery ajax HTML表单提交调用未将控制权返回给调用程序
- javascript - Swiper - 无法在移动设备上禁用触摸
- d3.js - 基于最大值和最小值的热图颜色范围
- mysql - 如何跟踪数据库中的登录时间,以便我可以看到查询表的活跃用户
- node.js - 规范中没有定义操作!---无法定义定义---node.ts,swaggerUI
- android - 在使用 Android Studio 3.5.2 重新分析显示一些编码代码的 Android Studio XML 之后
- php - 简单数学表达式的动态计算