Skip to content

Cannot connect to FastAPI-based websocket server using the library while postman. #1624

@milk-bottle-liyu

Description

@milk-bottle-liyu

I create a server using FastAPI and websockets, which looks like

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
import asyncio 

app = FastAPI()

@app.websocket("/{group}/{player_name}")
async def websocket_endpoint(websocket: WebSocket, group, player_name):
    if group == 'human' and player_name == 'admin':
        if app.state.game_server.admin_sock is None:
            await websocket.accept()
        else:
            raise ValueError('admin connected')
        app.state.game_server.admin_sock = websocket
        logging.info(f'add admin')
    else:
        if player_name in app.state.game_server.game_config.player_list:
            raise ValueError(f'{player_name} conneccted')
        else:
            await websocket.accept()
        app.state.game_server.add_player(player_name, websocket)
        logging.info(f'add {player_name}')

    try:
        while True:
            data = await websocket.receive_text()
            logging.warning(f'from {player_name}: {data}')
            async with app.state.game_lock:
                await app.state.game_server.handle_msg(data, player_name)

            await asyncio.sleep(0.5)

    except WebSocketDisconnect:
        if group == 'human' and player_name == 'admin':
            app.state.game_server.admin_sock = None
        else:
            app.state.game_server.remove_player(player_name)
        logging.warning(f"player [{player_name}] disconnected")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],

    allow_headers=["*", "Upgrade", "Connection"]
)

I try to connect the server using code below.

    import asyncio
    import signal

    from websockets.asyncio.client import connect as aconnect


    async def client():
        async with aconnect("ws://127.0.0.1:8000/agent/kimi") as websocket:
            # Close the connection when receiving SIGTERM.
            loop = asyncio.get_running_loop()
            loop.add_signal_handler(signal.SIGTERM, loop.create_task, websocket.close())

            # Process messages received on the connection.
            async for message in websocket:
                print(message)


    asyncio.run(client())

But it fails with outputs as follow.

Traceback (most recent call last):
  File "C:\Users\****\miniconda3\envs\wiu\lib\site-packages\websockets\http11.py", line 241, in parse
    status_line = yield from parse_line(read_line)
  File "C:\Users\****\miniconda3\envs\wiu\lib\site-packages\websockets\http11.py", line 309, in parse_line
    line = yield from read_line(MAX_LINE_LENGTH)
  File "C:\Users\****\miniconda3\envs\wiu\lib\site-packages\websockets\streams.py", line 46, in read_line
    raise EOFError(f"stream ends after {p} bytes, before end of line")
EOFError: stream ends after 0 bytes, before end of line

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\****\miniconda3\envs\wiu\lib\site-packages\websockets\client.py", line 301, in parse
    response = yield from Response.parse(
  File "C:\Users\****\miniconda3\envs\wiu\lib\site-packages\websockets\http11.py", line 243, in parse
    raise EOFError("connection closed while reading HTTP status line") from exc
EOFError: connection closed while reading HTTP status line

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "D:\code\****\BaseAgentPlayer.py", line 186, in <module>
    asyncio.run(client())
  File "C:\Users\****\miniconda3\envs\wiu\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\****\miniconda3\envs\wiu\lib\asyncio\base_events.py", line 649, in run_until_complete
    return future.result()
  File "D:\code\****\BaseAgentPlayer.py", line 176, in client
    async with aconnect("ws://127.0.0.1:8000/agent/kimi") as websocket:
  File "C:\Users\****\miniconda3\envs\wiu\lib\site-packages\websockets\asyncio\client.py", line 587, in __aenter__
    return await self
  File "C:\Users\****\miniconda3\envs\wiu\lib\site-packages\websockets\asyncio\client.py", line 543, in __await_impl__
    await self.connection.handshake(
  File "C:\Users\****\miniconda3\envs\wiu\lib\site-packages\websockets\asyncio\client.py", line 114, in handshake
    raise self.protocol.handshake_exc
websockets.exceptions.InvalidMessage: did not receive a valid HTTP response

I can connect to the server using postman and a client writen in vue, so I found it quite strange to me.

Please help with the issue~

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions