Skip to content

Questions about consumer_handler and registration examples in intro #457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wardbradt opened this issue Aug 16, 2018 · 4 comments
Closed

Comments

@wardbradt
Copy link

Consumer Handler Question

Hi, I was looking at the consumer_handler example in the intro. I was wondering if you could help me figure out how to have this example run forever (i.e. until CTRL + C).

Here is a modification of the example in the intro,

async def consumer_handler(websocket, path):
    async for message in websocket:
        print(message)

This code will print every message sent from websocket, correct?
Under the example, it says

Iteration terminates when the client disconnects

Does this mean consumer_handler is effectively a while True loop? And "when the client disconnects," does the loop exit or is an error (ConnectionClosed?) raised? How could I use this same example but with ssl?


Registration/ Multiple Connection Question

How could I run consumer_handler for multiple WebSocket connections?
Would the below code work? (Modified from the original registration example)

connected = set()
connected.add(websockets.serve(consumer_handler, 'wss://api.foo.com', 8765))
connected.add(websockets.serve(consumer_handler, 'wss://api.bar.com', 8765))
connected.add(websockets.serve(consumer_handler, 'wss://api.foobar.com', 8765))

async def handler():
    try:
        await asyncio.wait([ws for ws in connected])
    finally:
        # Unregister.
        connected.remove(websocket)

I am currently just learning how to use WebSockets, so your help is very much appreciated. Obviously, thanks for creating such an awesome library.

@wardbradt
Copy link
Author

For anyone who finds this the answer is:

import asyncio
import websockets

connections = set()
connections.add('wss://api.foo.com:8765')
connections.add('wss://api.bar.com:8765'))
connections.add('wss://api.foobar.com:8765'))

async def handle_socket(uri, ):
    async with websockets.connect(uri) as websocket:
        async for message in websocket:
            print(message)

async def handler():
    await asyncio.wait([handle_socket(uri) for uri in connections])

asyncio.get_event_loop().run_until_complete(handler())

@aaugustin
Copy link
Member

I was wondering if you could help me figure out how to have this example run forever (i.e. until CTRL + C).

That's what asyncio.get_event_loop().run_forever() does.

If you want to avoid displaying a stack trace:

try:
    asyncio.get_event_loop().run_forever()
except KeyboardInterrupt:
    pass

This code will print every message sent from websocket, correct?

Yes.

Does this mean consumer_handler is effectively a while True loop?

It'd be better to think of it as an (async) iterator than a while True loop.

And "when the client disconnects," does the loop exit or is an error (ConnectionClosed?) raised?

This is a bit hidden in the documentation, here: https://websockets.readthedocs.io/en/stable/api.html#websockets.protocol.WebSocketCommonProtocol: "The iterator yields incoming messages. It exits normally when the connection is closed with the status code 1000 (OK) or 1001 (going away). It raises a ConnectionClosed exception when the connection is closed with any other status code."

I'll consider improving the docs.

How could I use this same example but with ssl?

It depends whether you're writing a server or a client — you didn't specify. Both cases are covered here: https://websockets.readthedocs.io/en/stable/intro.html#secure-example

How could I run consumer_handler for multiple WebSocket connections?

The code you provided suggests you misunderstood the API of serve. The second argument is an IP address to bind to (or 0.0.0.0 to listen on all network interfaces), not a websocket URI. serve will accept multiple connections and run the handler once per connection.

@aaugustin
Copy link
Member

Just saw your second comment...

If you're writing a client (connect rather than serve), then yes, your approach to multiple connections is correct.

The revised code example is sensible (just a couple typos).

@wardbradt
Copy link
Author

Thanks for the reply anyway. I definitely am writing a client. The API section in the documentation was a great help.

@aaugustin aaugustin mentioned this issue Jun 23, 2019
18 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants