I'm developing a web app using Django Channels. It needs to serve HTTP requests and also accept websockets connections. In local everything runs fine, but I'm having trouble in Azure. It rejects the websockets connections (HTTP code 503). I've tried everything I found, but I can't seem to solve it. I think the problem is with daphne or azure load balancers, because there's nothing relating to the failed connections on the logs.
I'm using App Service on Azure with python (3.8). The websockets switch is on, and the startup command is:
daphne -b 0.0.0.0 bstore_server.asgi:application -v 3
My asgi.py file is:
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
# Important que vagi aquí dalt
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bstore_server.settings.production')
asgi_application = get_asgi_application()
from channels.auth import AuthMiddlewareStack
import bstore_server_app.routing
application = ProtocolTypeRouter({
'http': asgi_application,
'websocket': AuthMiddlewareStack(
URLRouter(
bstore_server_app.routing.websockets_urlpatterns
)
),
})
And here's my client (needless to say it works on the local server):
import asyncio
import websockets
import json
import ssl
from websockets.exceptions import ConnectionClosedError, WebSocketException
station_id = '0824201'
# uri = f'ws://127.0.0.1:8000/ws/station/{station_id}/'
uri = f'wss://bstore-test.azurewebsites.net/ws/station/{station_id}/'
ssl_context = ssl.create_default_context()
ssl_context.options |= ssl.PROTOCOL_TLS
async def server_connect():
while True:
try:
async with websockets.connect(uri, ssl=ssl_context) as websocket:
print('>>> S\'ha connectat')
# Espera peticions
try:
async for message in websocket:
print(f'>>> S\'ha rebut una petició: {message}')
data = json.loads(message)
action = data.get('action')
params = data.get('params')
id = data.get('id')
if action is None or params is None or id is None:
print('>>> La petició no és vàlida')
continue
if action == 'open' or action=='lock':
await websocket.send(json.dumps({
'result': 'ok',
'id': id,
}))
else:
await websocket.send(json.dumps({
'error': [
{
'code': 'generic',
'message': 'Acció desconeguda',
},
],
'id': id,
}))
finally:
print('>>> S\'ha desconnectat')
except ConnectionClosedError:
print('>>> S\'ha tancat la connexió. Es tornarà a provar de connectar en 10 s...')
except ConnectionRefusedError:
print('>>> El servidor remot no està disponible. Es tornarà a provar de connectar en 10 s...')
except WebSocketException as ex:
print(f'>>> S\'ha produït un error ({ex}). Es tornarà a provar de connectar en 10 s...')
await asyncio.sleep(10)
# Event loop
loop = asyncio.get_event_loop()
loop.create_task(server_connect())
loop.run_forever()
The channel layer is working fine using Azure Cache for Redis. In local, but using the same channel layer backend everything works. And in azure, I've tested it in the shell.
I've read almost everything I've found on Google but it either wasn't related or unhelpful.
Has anyone run into the same problem?