Skip to content

Awaiting on WebSocketResponse.send_* does not work #1645

Closed
@mind1m

Description

Long story short

In documentation it says:

New in version 1.3.0.
To enable back-pressure from slow websocket clients treat methods ping(), pong(), send_str(), send_bytes(), send_json() as coroutines. By default write buffer size is set to 64k.

http://aiohttp.readthedocs.io/en/stable/web_reference.html?highlight=back%20pressure#websocketresponse

However, if I try to do it, I get:

Error handling request
Traceback (most recent call last):
  File ".../env/lib/python3.6/site-packages/aiohttp/web_server.py", line 62, in handle_request
    resp = yield from self._handler(request)
  File ".../env/lib/python3.6/site-packages/aiohttp/web.py", line 270, in _handle
    resp = yield from handler(request)
  File "ws_srv.py", line 8, in wshandler
    await ws.send_str('hello')
TypeError: object tuple can't be used in 'await' expression

It can be seen, that when writer's buffer is not full, WebSocketWriter._send_frame returns a tuple https://github.com/KeepSafe/aiohttp/blob/e49b59b0594ca4c21a3f788ffcbe0005c79daa65/aiohttp/_ws_impl.py#L457 . Maybe it should be async function or return a Future?

Expected behaviour

Awaiting on WebSocketResponse.send_* should work.

Actual behaviour

Awaiting on WebSocketResponse.send_* when buffer is not full results in TypeError: object tuple can't be used in 'await' expression.

Steps to reproduce

ws_server.py

import asyncio
from aiohttp.web import Application, WebSocketResponse, run_app


async def wshandler(request):
    ws = WebSocketResponse()
    await ws.prepare(request)
    await ws.send_str('hello')
    await ws.close()
    print('Processed client')
    return ws

async def init(loop):
    app = Application(loop=loop)
    app.router.add_get('/', wshandler)
    return app

loop = asyncio.get_event_loop()
app = loop.run_until_complete(init(loop))
run_app(app)

ws_client.py

import asyncio
import aiohttp


async def f():
    session = aiohttp.ClientSession()
    async with session.ws_connect('http://localhost:8080') as ws:
        answer = await ws.receive_str()
        assert answer == 'hello'
        print('Got correct answer, exiting..')
    await session.close()

asyncio.get_event_loop().run_until_complete(f())

Your environment

aiohttp 1.3.1, Python 3.6, OS 10.12.2

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions