【问题标题】:Django, Vue and WebSocket - getting client side to workDjango、Vue 和 WebSocket - 让客户端工作
【发布时间】:2021-10-20 20:12:00
【问题描述】:

前段时间在 SO 上有一个类似的问题,尽管我尝试了答案但没有运气。

我正在使用 Django 后端和带有 Vue cli 的 Vue 前端来实现一个 SPA。 Django 正在使用通道通过 WebSocket 将 JSON 发送到前端,前端接收此数据并应该更新表。

Django 部分正在工作。已确认与 WebSocket 的连接并在 Vue 中接收到数据,但我有两个问题我无法找到解决方法:

  1. 数据在变量中时未显示在表格中,并且
  2. 前端只接收一次数据 - 我不知道如何将侦听器应用到 WebSocket,或者在我的 Vue 应用程序的哪个部分,以便接收到新的有效负载(我希望我说的没错)并相应更新。

下面我提供了 Django consumer.py 文件、Signals.vue 视图文件和 console.log 输出,显示该变量确实包含 JSON 对象,尽管表仍为空白。

有没有人知道我哪里出了问题以及如何解决问题 1 和 2? 谢谢

Django 消费者.py

import json
from channels.generic.websocket import WebsocketConsumer


class WSConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()

        self.send(json.dumps({
            'id': 1,
            'date': "date",
            'marketOpen': "marketOpen",
            'symbol': "symbol",
            'trade': "trade",
            'bias': "bias",
            'status': "status"
            }))

Signals.vue

<template>
    <div class="container">
        <div class="columns is-multiline">
            <div class="column is-12">
                <h1 class="title"> Signals</h1>
            </div>

            <div class="column is-12">
                <table class="table is-fullwidth">
                    <thead>
                        <tr>
                            <th>Date</th>
                            <th>Market Open</th>
                            <th>Symbol</th>
                            <th>Trade</th>
                            <th>Bias</th>
                            <th>Status</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for= "signal in signals" v-bind:key="signal.id">
                            <td>{{ signal.date }} </td>
                            <td>{{ signal.marketOpen }} </td>
                            <td>{{ signal.symbol }} </td>
                            <td>{{ signal.trade }} </td>
                            <td>{{ signal.bias }} </td>
                            <td>{{ signal.status }} </td>
                        </tr>
                    </tbody>    
                </table>
            </div>
            
        </div>
    </div>
</template>

<script>
export default {
    name: 'Signals',
    data() {
        return {
            signals: [],
            connection: null
        }
    },
    created() {
        this.getSignals()
    },
    methods: {
        getSignals() {
            console.log("Starting connection to websocket")
            this.connection = new WebSocket('ws://localhost:8000/ws/signals/')
            this.connection.onmessage = (event) => {
                this.signals = event.data
                console.log("Successfully retrieved message from websocket")
                console.log(this.signals)
            }
        }
    }
}
</script>

控制台

[HMR] Waiting for update signal from WDS... log.js?1afd

Starting connection to websocket Signals.vue?1d80

Unchecked runtime.lastError: The message port closed before a response was received. signals:1

Successfully retrieved message from websocket Signals.vue?1d80

{"id": 1, "date": "date", "marketOpen": "marketOpen", "symbol": "symbol", "trade": "trade", "bias": "bias", "status": "status"} Signals.vue?1d80

【问题讨论】:

  • 你有没有让这个工作?
  • 是的 - 它只发送一次,因为它只是消费者只运行一次。我设置了 celery 任务并创建了一个每 x 分钟/小时/天等运行一次的任务,这解决了问题。

标签: django vue.js websocket


【解决方案1】:

要异步发送消息,您应该使用异步, 并编写一个异步函数来根据要求发送数据,调用 view.py 或 celery worker 中的 send 函数,如果你想定期发送 celery beat 是要走的路,否则使用 celery worker 来按需数据。

这是我第一次在堆栈中回答,如果我对问题的理解或回答有任何错误,请原谅我。我不确定你的第一个问题是什么。 (我刚开始学习 Vue js,但我在 Django 上工作了多年,所以我想我可以回答这个问题,感谢所有在 Stackoverflow.com 上帮助我回复的人)

下面是我实现的套接字连接的一个简单示例:

class NotificationConsumer(AsyncWebsocketConsumer):
async def connect(self):
    # this only exicutes only once when a user gets connected to the socket
    self.room_name = self.scope['url_route']['kwargs']['room_name']
    self.room_group_name = 'notification_%s' % self.room_name

    # Join room group
    await self.channel_layer.group_add(
        self.room_group_name,
        self.channel_name
    )

    await self.accept()

async def disconnect(self, close_code):
    # Leave room group
    await self.channel_layer.group_discard(
        self.room_group_name,
        self.channel_name
    )

Receive message from WebSocket
async def receive(self, text_data):
    text_data_json = json.loads(text_data)
    message = text_data_json['message']
    print(message)
    print("message")

    # Send message to room group
    await self.channel_layer.group_send(
        self.room_group_name,
        {
            'type': 'snmpop_message',
            'message': message
        }
    )


async def send_notification(self, event):
    message = json.loads(event['message'])
    print(message)
    # Send message to WebSocket
    await self.send(text_data=json.dumps(message))

#这就是我将根据要求发送数据的方式:从任何其他地方:

channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
    "notification_broadcast",
    {
        'type': 'send_Notification',
        'message': json.dumps(outputdict)
    }
 )

如果你们有任何疑问,可以联系我:amithkhul@gmail.com 谢谢 阿米特·K

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多