2

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?

Daniel
  • 61
  • 4
  • Can you share your daphne logs? – lucutzu33 Jun 09 '21 at 20:55
  • The thing is the connection doesn’t even appear on the logs. I can see the error on azure portal, but the connection doesn’t seem to even reach daphne – Daniel Jun 09 '21 at 21:45
  • Is any firewall on? – lucutzu33 Jun 09 '21 at 21:56
  • No, there isn’t any firewall on, nor any access restrictions – Daniel Jun 10 '21 at 05:46
  • I've changed the startup command to use unicorn with uvicorn and the problem persists. I get the same response and nothing gets registered in the application logs. – Daniel Jun 10 '21 at 17:43
  • https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#network-endpoint-listening -> The only way an application can be accessed via the internet is through the already-exposed HTTP (80) and HTTPS (443) TCP ports; applications may not listen on other ports for packets arriving from the internet. – lucutzu33 Jun 10 '21 at 17:57
  • https://stackoverflow.com/questions/24044839/windows-azure-node-js-websocket-handshake-fails-503-error Maybe this will also help. – lucutzu33 Jun 10 '21 at 17:58
  • Thanks Ene P, I’ll tinker with the ports. By the way, I had websockets on already. – Daniel Jun 11 '21 at 13:39
  • I've finally desisted and switched to a VPS. – Daniel Jun 17 '21 at 06:39
  • Haha, good..... – lucutzu33 Jun 17 '21 at 07:32

0 Answers0