from channels.generic.websocket import AsyncWebsocketConsumer
from channels.consumer import AsyncConsumer
from channels.layers import get_channel_layer
import json
import asyncio
import aiohttp
import datetime
class mainConsumer(AsyncWebsocketConsumer):
async def connect(self):
await self.channel_layer.group_add('myGroup', self.channel_name)
await self.accept()
async def disconnect(self, closeCode):
await self.channel_layer.group_discard('myGroup', self.channel_name)
async def receive(self, text_data):
eventData = json.loads(text_data)
print(eventData)
if eventData['toggle'] == 'on':
await self.channel_layer.send('myToggle',{"type": "openConnection"})
elif eventData['toggle'] == 'off':
await self.channel_layer.send('myToggle',{"type": "closeConnection"})
async def myUpdate(self, data):
updateMsg = #some data processing here
await self.send(text_data=json.dumps(updateMsg))
class backgroundConsumer(AsyncConsumer):
def __init__(self, scope):
self.scope = scope
self.turnOnListener = True
self.channelLayer = get_channel_layer()
self.t1 = None
print('inside init') # this will print init on every channel_layer.send to 'myToggle' in mainConsumer
async def listen(self):
async with aiohttp.ClientSession() as session:
async with session.ws_connect('...streaming url...', ssl=False) as ws:
await ws.send_str('...some string...')
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
if msg.data.startswith('2'):
await ws.send_str('3')
else:
await self.parseListenData(msg)
async def parseListenData(self, msgContent):
# process and create updateMsg dict with type: 'myUpdate' (so that it gets to the myUpdate function in main Consumer)
await self.channelLayer.group_send('myGroup', updateMsg)
async def openConnection(self, event):
if(self.turnOnListener): # THIS IS ALWAYS TRUE BECAUSE THE ROUTE INITIALIZES A NEW INSTANCE OF THIS CLASS!!
await self.channelLayer.group_add(
'myGroup',
self.channel_name,
)
self.turnOnListener = False # This only changes it for the current instance (obviously)
loop = asyncio.get_event_loop()
self.t1 = asyncio.run_coroutine_threadsafe(self.listen(), loop=loop)
else:
print('already turned on listener')
async def closeConnection(self, event):
loop = asyncio.get_event_loop()
loop.call_soon_threadsafe(self.t1.cancel) # t1 is always None because the route initialized a new instance of this class!!