无法使用Django频道从头到尾发送消息

时间:2019-01-30 07:08:20

标签: javascript django

我可以从头到尾发送数据,但是将消息从consumers.py中的WebSocket接收函数发送消息到中的socket.onmessage中存在问题 thread.html。这是两个代码:

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)
        await self.send({
            "type": "websocket.accept"
        })

        other_user = self.scope['url_route']['kwargs']['username']
        me = self.scope['user']
        thread_obj = await self.get_thread(me, other_user)

    async def websocket_receive(self, event):
        print("receive", event)
        front_text = event.get('text', None)
        if front_text is not None:
            loaded_dict_data = json.loads(front_text)
            msg = loaded_dict_data.get('message')
            print(msg)
            user = self.scope['user']
            username = 'default'
            if user.is_authenticated:
                username = user.username
            myResponse = {
                'message': "this is a instant message",
                'username': username
            }
            await self.send({
                "type": "Websocket.send",
                "text": json.dumps(myResponse),
            })
        # {'type': 'websocket.receive', 'text': '{"message":myResponse}'}

    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]

我已经在websocket接收器中放入了打印功能,它被调用了,但是我不确定self.send,我不知道该怎么发送

这是thread.html:

{% extends "base.html" %}
{% block content %}
<p>Thread for {% if user != object.first %}{{ object.first }}{% else %}{{ object.second }}{% endif %}</p>
<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 %}
    <input type="hidden" id="myUsername" value='{{ user.username }}'>
{{form.as_p }}
<input type='submit' class='btn btn-primary'/>
</form>

{% endblock %}

{% block script %}

<script>
// websocket scripts
console.log(window.location);
var loc = window.location;
var formData = $("#form");
var msgInput = $("#id_message");
var chatHolder = $("#chat-items");
var me = $('#myUsername').val()

var wsStart = 'ws://';
if(loc.protocol === 'https:'){
    wsStart = 'wss://'
}
var endpoint = wsStart + loc.host + loc.pathname;
var socket = new WebSocket(endpoint);


socket.onmessage = function(e){
    console.log("message",e);
    var chatDataMsg = JSON.parse(e.data);
    chatHolder.append("<li>"+ chatDataMsg.message + "via" + chatDataMsg.username + "</li>")
};

socket.onopen = function(e){
    console.log("open",e);
    formData.submit(function (event) {
        event.preventDefault();
        var msgText = msgInput.val();
        chatHolder.append("<li>"+ msgText + " via " + me + "</li>")
        var finalData = {
            'message': msgText
        };
       // var formDataSerialized = formData.serialize()
        socket.send(JSON.stringify(finalData));
        formData[0].reset()
    })
};
socket.onerror = function(e){
    console.log("error",e)
};
socket.onclose = function(e){
    console.log("close",e)
}

</script>
{% endblock %}

1 个答案:

答案 0 :(得分:0)

我更改了Consumer.py,现在可以使用了:

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)
        self.get_thread_obj = thread_obj
        chat_room = "thread_{}".format(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):
        front_text = event.get('text', None)
        if front_text is not None:
            loaded_dict_data = json.loads(front_text)
            msg = loaded_dict_data.get('message')
            user = self.scope['user']
            username = 'default'
            if user.is_authenticated:
                username = user.username
            myResponse = {
                'message': msg,
                'username': username
            }

            await self.create_chat_message(user, msg)

            await self.channel_layer.group_send(
                self.chat_room,
                {
                    "type": "chat_message",
                    "text": json.dumps(myResponse)
                }
            )

    async def chat_message(self, event):
        await self.send({
            "type": "websocket.send",
            "text": event['text']
        })

    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]

    @database_sync_to_async
    def create_chat_message(self, me, msg):
        thread_obj = self.get_thread_obj
        return ChatMessage.objects.create(thread=thread_obj, user=me, message=msg)