I am using Django Channel for a real-time sending and saving data but when I refresh the page the error came up. I don't know why but, on first load the system is okay but if I reload the page the log appears.
Application instance <Task pending name='Task-1' coro=<StaticFilesWrapper.__call__() running at /home/planet/Dhruvil/DRF/websoket/venv/lib/python3.10/site-packages/channels/staticfiles.py:44> wait_for=<_GatheringFuture pending cb=[Task.task_wakeup()]>> for connection <WebRequest at 0x7f2535d4d7e0 method=GET uri=/stock-info/?symbol=SBIN clientproto=HTTP/1.1> took too long to shut down and was killed.
The above exception occurs and the entire service stops running. how i solve this error.
consumers.py
class StockInfoConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
self.room_name = 'stock_consumer'
self.room_group_name = 'stock_updates'
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
async def receive(self, text_data):
print(text_data)
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
await self.close()
raise StopConsumer()
async def send_stock_info(self, event):
stock_info = json.loads(event.get('stock_info'))
await self.send(text_data=json.dumps({'payload' : stock_info}))
views.py
def get_one_stock_info(symbol):
stock_info = {}
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
}
baseurl = "https://query2.finance.yahoo.com/"
url = f"https://query2.finance.yahoo.com/v8/finance/chart/{symbol}.NS"
session = requests.Session()
request = session.get(baseurl, headers=headers, timeout=5)
cookies = dict(request.cookies)
while True:
response = session.get(url, headers=headers, timeout=5, cookies=cookies)
if response.status_code == 200:
try:
data = response.json()
stock_info['Symbol'] = symbol
stock_info['Price'] = data['chart']['result'][0]['meta']['regularMarketPrice']
stock_info['High'] = data['chart']['result'][0]['meta']['regularMarketDayHigh']
stock_info['Low'] = data['chart']['result'][0]['meta']['regularMarketDayLow']
stock_info['Volume'] = data['chart']['result'][0]['meta']['regularMarketVolume']
stock_info['PreviousClose'] = data['chart']['result'][0]['meta']['previousClose']
return stock_info
except json.JSONDecodeError as e:
print(f"Error decoding JSON: {e}")
else:
print(f"Error fetching data. Status code: {response.status_code}")
time.sleep(0.0001)
return stock_info
class OneStockInfoAPIView(APIView):
def get(self, request):
symbol = request.query_params.get('symbol')
if not symbol:
return Response({'error': 'symbol parameter is required'}, status=status.HTTP_400_BAD_REQUEST)
while True:
stock_info = get_one_stock_info(symbol)
# Send stock info over WebSocket
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'stock_updates', # Group name
{
'type': 'send_stock_info',
'stock_info': json.dumps(stock_info),
}
)
time.sleep(1)
StockInfo.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const StockInfo = () => {
const [stockData, setStockData] = useState(null);
const [ws, setWs] = useState(null);
useEffect(() => {
// Fetch stock data from REST API
axios.get('http://127.0.0.1:8000/stock-info/?symbol=SBIN')
.then(response => {
setStockData(response.data);
})
.catch(error => {
console.error('Error fetching stock data:', error);
});
// Connect to WebSocket for live updates
const newWs = new WebSocket('ws://127.0.0.1:8000/ws/stock-info/');
newWs.onopen = () => {
console.log('WebSocket connection opened');
};
newWs.onmessage = (event) => {
const newData = JSON.parse(event.data);
console.log('Received new stock data:', newData);
setStockData(newData.payload);
};
newWs.onerror = (error) => {
console.error('WebSocket error:', error);
};
setWs(newWs);
return () => {
console.log('Closing WebSocket connection');
newWs.close();
};
}, []);
const handlePageUnload = () => {
if (ws) {
console.log('Closing WebSocket connection on page unload');
ws.close();
}
};
useEffect(() => {
window.addEventListener('beforeunload', handlePageUnload);
return () => {
window.removeEventListener('beforeunload', handlePageUnload);
};
}, [ws]);
const getPriceColor = () => {
if (!stockData) return ''; // Default color if data is not yet loaded
return stockData.Price < stockData.PreviousClose ? 'red' : 'green';
};
return (
<div>
<center>
<h1>Live Stock Data</h1>
{stockData && (
<div>
<p>Symbol: {stockData.Symbol}</p>
<p style={{ color: getPriceColor() }}>Price: {stockData.Price}</p>
<p>High: {stockData.High}</p>
<p>Low: {stockData.Low}</p>
<p>Volume: {stockData.Volume}</p>
<p>Previous Close: {stockData.PreviousClose}</p>
{/* Add more data fields as needed */}
</div>
)}
</center>
</div>
);
};
export default StockInfo;