我仍然是django-channels的新手,并且直接从频道2.0开始,所以各种各样的例子仍然有点难以找到。我试图了解如何在通道中创建异步进程并让js客户端监听它?
在连接到我的消费者时,我正在检查线程上的正在运行的流并尝试在通道上发回预测。这个过程是异步的,但我不确定如何正确使用AsyncConsumer或AsyncJsonWebsocketConsumer。
到目前为止,我有一个像这样的简单消费者: 的 consumers.py
import threading
from sklearn.externals import joblib
from channels.generic.websocket import JsonWebsocketConsumer
from .views import readStream
class My_Consumer(JsonWebsocketConsumer):
groups = ["broadcast"]
the_thread_name = 'TestThread'
def connect(self):
the_thread = None
self.accept()
# check if there is an active stream on a thread
for thread in threading.enumerate():
if thread.name == self.the_thread_name:
the_thread = thread
break
if the_thread == None:
xsLog.infoLog('No Stream found yet...')
self.close()
else:
the_stream = readStream()
#...
the_estimator = joblib.load('some_file','r')
the_array = np.zeros(shape=(1,93), dtype=float)
self.predict(the_thread,the_stream,the_array,the_estimator)
def disconnect(self,close_code):
pass
async def predict(self,the_thread,the_stream,the_array,the_estimator):
while the_thread.isAlive():
sample = await the_stream.read()
if sample != [0.0,0.0,0.0] and 'nan' not in str(sample):
the_array = np.roll(self.the_array,-3)
the_array[0][-3] = sample[0]
the_array[0][-2] = sample[1]
the_array[0][-1] = sample[2]
new_val = await '{},{}'.format(the_estimator.predict(the_array)[0][0],the_estimator.predict(the_array)[0][1])
await self.send_json(new_val)
我的 js客户端非常简单,并试图倾听:
const webSocketBridge = new channels.WebSocketBridge();
webSocketBridge.connect('some_route');
webSocketBridge.socket.addEventListener('open', function() {
console.log("Connected to WebSocket");
});
webSocketBridge.listen(function(message, stream) {console.log(message);});
编辑
从上面提到的问题我尝试使用 AsyncJsonWebsocketConsumer 的以下简化解决方案:
import threading
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from channels.db import database_sync_to_async
class My_Consumer(AsyncJsonWebsocketConsumer):
groups = ["broadcast"]
the_thread = None
the_data = None
#
@database_sync_to_async
def getUserData(self,the_user):
return models.UserData.objects.filter(user=the_user,datatype='codebooks')
#
async def connect(self):
await self.accept()
for thread in threading.enumerate():
if thread.name == 'some_thread_name':
self.the_thread = thread
break
if self.the_thread == None:
xsLog.infoLog('No Stream found yet...')
await self.close()
else:
the_data = await self.getUserData(the_user)
#
async def receive(self,content=None,text_data=None):
await self.predict(self.the_thread,self.the_data)
#
async def predict(self,the_thread,the_data):
"""..."""
while the_thread.isAlive():
# doing something here
new_data = data_from_thread + the_data
self.send_json(new_data)
#
async def disconnect(self,close_code):
await self.close()
然后我通过 JS客户端发送一条消息来初始化消费者的接收方法:
webSocketBridge.socket.addEventListener('open', function() {
console.log("Connected to WebSocket, Launching Predictions");
webSocketBridge.send('');
});
这里的问题是,当启动预测协程时,它会阻止整个接收,并且我的js客户端无法通过以下方式接收任何消息:
webSocketBridge.listen(function(message, stream) {
console.log(message.stream);
});
然后也无法识别断开协程。