python - 没有消息类型 websocket.group_send 的处理程序,如何解决?

标签 python django websocket django-channels

我从一个用户的 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)

关于python - 没有消息类型 websocket.group_send 的处理程序,如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57443549/

相关文章:

python - 无法以足够的精度将 matlab datenum 格式转换为 python datetime

python - 用大叶制作等值线图

django - 如何将日期选择器和时间选择器添加到 Django forms.SplitDateTimeField?

ios - 重新连接到 websockets 的适当时间间隔

javascript - 如何从 React 中的 Websocket 获取数据?

python - SQLite 不在使用之间保存数据

python - 如何更新 Django 中的多对多字段?

Django:构建全局模板标签的最佳实践是什么?

django - 为什么 psycopg2 可以连接到我的数据库而我却不能

websocket - JMeter Websocket : How to answer incoming pings with pongs while timer?