question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unexpected ASGI message 'websocket.send', after sending 'websocket.close'.

See original GitHub issue

Hi, I am just connecting the users to websocket and returning the list of all connected users.

When i connect the first user everything works fine. But once i connect another user I get the following error:

Traceback (most recent call last):
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 154, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/fastapi/applications.py", line 179, in __call__
    await super().__call__(scope, receive, send)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/starlette/applications.py", line 111, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/starlette/middleware/errors.py", line 146, in __call__
    await self.app(scope, receive, send)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/starlette/exceptions.py", line 58, in __call__
    await self.app(scope, receive, send)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/starlette/routing.py", line 566, in __call__
    await route.handle(scope, receive, send)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/starlette/routing.py", line 283, in handle
    await self.app(scope, receive, send)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/starlette/routing.py", line 57, in app
    await func(session)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/fastapi/routing.py", line 228, in app
    await dependant.call(**values)
  File "./main.py", line 110, in connect_user
    await socket_manager.get_online_users()
  File "./users/views.py", line 224, in get_online_users
    await connection[0].send_json({"sender": response.get('sender')})
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/starlette/websockets.py", line 137, in send_json
    await self.send({"type": "websocket.send", "text": text})
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/starlette/websockets.py", line 68, in send
    await self._send(message)
  File "/home/ahtisham/ENVS/ENV_COLLAB/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 231, in asgi_send
    raise RuntimeError(msg % message_type)
RuntimeError: Unexpected ASGI message 'websocket.send', after sending 'websocket.close'.

I found this issue but that doesn’t work in my case.

websocket manager:

class SocketManager:
    def __init__(self):
        self.active_connections: List[(WebSocket, models.User)] = []

    async def connect(self, websocket: WebSocket, user: models.User):
        await websocket.accept()
        self.active_connections.append((websocket, user))

    async def get_online_users(self):
        response = {"receivers": []}
        for connection in self.active_connections:
            response['receivers'].append(connection[1].username)

        for connection in self.active_connections:
            response.update({"sender": connection[1].username})
            # this is causing the problem
            await connection[0].send_json(response)

websocket endpoint

socket_manager = SocketManager()

@app.websocket("/api/user-connect")
async def connect_user(websocket: views.WebSocket, db: Session = Depends(get_db)):
    user = views.get_current_user(db, websocket.cookies.get("access_token"))
    if user:
         # connect user to a websocket
        await socket_manager.connect(websocket, user)
        # broadcast the connected list of users.
        await socket_manager.get_online_users()

JavaScript code:

var socket = new WebSocket("ws://127.0.0.1:8000/api/user-connect");
socket.onmessage = function(event) {
        var data = JSON.parse(event.data);
        var sender = data['sender'];
        console.log(sender);              
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
Mausecommented, Nov 18, 2020

If I had to guess, I’d say after your connect_user function exits, your websocket closes, so your socket manager just tries to send messages to closed sockets.

You probably want a loop recieving messages at the end of it instead

2reactions
Ahtiicommented, Nov 18, 2020

@Mause This fixed the problem 😃

@app.websocket("/api/user-connect")
async def connect_user(websocket: views.WebSocket, db: Session = Depends(get_db)):
    user = views.get_current_user(db, websocket.cookies.get("access_token"))
    if user:
        await socket_manager.connect(websocket, user)
        await socket_manager.get_online_users()
        try:
            while True:
                data = await websocket.receive_json()
                print(data)
        except WebSocketDisconnect:
            socket_manager.disconnect(websocket, user)
Read more comments on GitHub >

github_iconTop Results From Across the Web

RuntimeError: Unexpected ASGI message 'websocket.send ...
The error "RuntimeError: Unexpected ASGI message 'websocket.send', after sending 'websocket.close'" literally means that you are trying to ...
Read more >
Unexpected ASGI message 'websocket.close', after sending ...
RuntimeError : Unexpected ASGI message 'websocket. close', after sending 'websocket. close' - Models - Hugging Face Forums.
Read more >
tiangolo/fastapi - Gitter
RuntimeError : Unexpected ASGI message 'websocket.send', after sending 'websocket.close'. this happens when a client sends something wrong into the websocket ...
Read more >
ASGI from scratch - WebSocket - Shen's Blog
It shows when each type of ASGI messages are sent and received. Every WebSocket connection starts with a websocket.connect message.
Read more >
WebSocket (ASGI Only) — Falcon 3.1.1 documentation
On the other hand, the ASGI spec requires the ASGI server to silently consume messages sent by the app after the connection has...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found