Django, Vue и WebSocket - обеспечение работы на стороне клиента

На SO был похожий вопрос об этом некоторое время назад, хотя я пробовал ответы и они не сработали.

Я реализую SPA с использованием Django backend и Vue front end с Vue cli. Django использует каналы для отправки JSON через WebSocket на фронтенд, фронтенд получает эти данные и должен обновить таблицу.

Часть Django работает. Соединение с WebSocket подтверждается и данные принимаются в Vue, хотя у меня есть две проблемы, которые я не смог найти способ решить:

  1. The data, while in a variable, is not being shown on the table and
  2. The front end only receives the data once - I don't know how to apply a listener to the WebSocket, or in which part of my Vue app, so that new payloads (I hope I am saying that correctly) are received and updated accordingly.

Ниже я привел файл Django consumers.py, файл представления Signals.vue и вывод console.log, показывающий, что переменная действительно содержит объект JSON, несмотря на то, что таблица остается пустой.

Есть ли у кого-нибудь идея, где я ошибаюсь и как я могу решить проблемы 1 и 2? Спасибо

Django consumers.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
Вернуться на верх