线程只能在Django通道中启动一次

问题描述 投票:0回答:2

我创建了一个简单的Django Channels使用者,该使用者应连接到外部源,检索数据并将其发送到客户端。因此,用户打开页面>使用者连接到外部服务并获取数据>数据被发送到Websocket。

这是我的代码:

import json
from channels.generic.websocket import WebsocketConsumer, AsyncConsumer, AsyncJsonWebsocketConsumer

from binance.client import Client
import json
from binance.websockets import BinanceSocketManager
import time
import asyncio

client = Client('', '')

trades = client.get_recent_trades(symbol='BNBBTC')
bm = BinanceSocketManager(client)
class EchoConsumer(AsyncJsonWebsocketConsumer):


    async def connect(self):
        await self.accept()
        await self.send_json('test')


        bm.start_trade_socket('BNBBTC', self.process_message)
        bm.start()


    def process_message(self, message):
        JSON1 = json.dumps(message)
        JSON2 = json.loads(JSON1)

        #define variables
        Rate = JSON2['p']
        Quantity = JSON2['q']
        Symbol = JSON2['s']
        Order = JSON2['m']

        asyncio.create_task(self.send_json(Rate))
        print(Rate)

当我打开一页时,此代码有效;但是,如果我尝试使用新帐户打开新窗口,则会引发以下错误:

File "C:\Users\User\Desktop\Heroku\github\master\myapp\consumers.py", line 54, in connect
    bm.start()
  File "C:\Users\User\lib\threading.py", line 843, in start
    raise RuntimeError("threads can only be started once")
  threads can only be started once

我是Channels的新手,所以这是一个菜鸟问题,但是我该如何解决这个问题?我想做的是:用户打开页面并获取数据,另一个用户打开页面并获取数据;有没有办法做到这一点?还是我只是误解了Django Channels和websockets的工作方式?

python django websocket django-channels
2个回答
0
投票

[我不是Django开发人员,但是如果我理解正确,函数connect被多次调用-并且bm.start引用了最有可能在bm.start_trade_socket(或connect中的其他地方)创建的同一线程。总之,当调用bm.start时,将启动一个线程,然后再次执行该线程,则会出现该错误。


0
投票

这里start()开始线程的活动。

每个线程对象最多应调用一次。您已将BinanceSocketManager的全局对象设置为“ bm”。

如果在同一线程对象上多次调用,它将始终引发RuntimeError。

请参考下面提到的代码,可能会对您有所帮助

from channels.generic.websocket import WebsocketConsumer, AsyncConsumer, AsyncJsonWebsocketConsumer

from binance.client import Client
import json
from binance.websockets import BinanceSocketManager
import time
import asyncio


class EchoConsumer(AsyncJsonWebsocketConsumer):
    client = Client('', '')

    trades = client.get_recent_trades(symbol='BNBBTC')
    bm = BinanceSocketManager(client)

    async def connect(self):
        await self.accept()
        await self.send_json('test')


        self.bm.start_trade_socket('BNBBTC', self.process_message)
        self.bm.start()


    def process_message(self, message):
        JSON1 = json.dumps(message)
        JSON2 = json.loads(JSON1)

        #define variables
        Rate = JSON2['p']
        Quantity = JSON2['q']
        Symbol = JSON2['s']
        Order = JSON2['m']

        asyncio.create_task(self.send_json(Rate))
        print(Rate)
© www.soinside.com 2019 - 2024. All rights reserved.