crossbario / autobahn-python

WebSocket and WAMP in Python for Twisted and asyncio
https://crossbar.io/autobahn
MIT License
2.48k stars 766 forks source link

Ability to connect to urls containing a path component. #1005

Closed ManuelSchneid3r closed 6 years ago

ManuelSchneid3r commented 6 years ago

I spend hours now to find out how to connect to a URL containing a path component. Still I have no clue how to achieve this. Although this is not strictly related to the code (I hope so) I opened this issue since the docs should contain an example on how to connect to urls like e.g. "wss://api.bitfinex.com/ws/2".

oberstet commented 6 years ago

Here is a client and two variants for a server https://github.com/crossbario/autobahn-python/tree/master/examples/twisted/websocket/multiproto

ManuelSchneid3r commented 6 years ago

Thats nice thank you. However it does not really help me since I use asyncio. The crucial part is the loop.create_connection(...) part I guess. When I pass a url containing a path I get socket.gaierror: [Errno -2] Name or service not known. If I remove the path nothing happens and the coroutine finishes instantly.

oberstet commented 6 years ago

you cannot listen on a URL, only on a port. what you can do is listen on the port and then dispatch to different websocket server backends based on the WebSocket URL, which contains the path. you can do like example1 in above on autobahn/asyncio. you cannot do the example2 pendent since that builds on Twisted Web for HTTP resource trees.

ManuelSchneid3r commented 6 years ago

Oh i think you got me wrong. I want my client to connect to a server. The url of the server contains a path like in my first post.

meejah commented 6 years ago

@ManuelSchneid3r you mean, you're writing a client? Do you control the server?

ManuelSchneid3r commented 6 years ago

Yes a client, no I dont control the server.

meejah commented 6 years ago

I think you'll have to ask the server operator for help, then, on how they're dispatching paths..?

Or, am I misunderstanding your problem? Have you tried the above-linked example, but with an asyncio client? e.g. https://github.com/crossbario/autobahn-python/blob/master/examples/asyncio/websocket/echo/client.py#L65 but with a path..?

ManuelSchneid3r commented 6 years ago

Pretty embarrassing. I didnt know that the create_connection returns instantly. Your modifications to my paste in IRC helped a lot. Thank you. For future readers I'll leave it here

import asyncio
import logging

from autobahn.asyncio.websocket import WebSocketClientProtocol, WebSocketClientFactory
from autobahn.websocket.util import parse_url
import txaio

class MyClientProtocol(WebSocketClientProtocol):

    done = asyncio.get_event_loop().create_future()

    def onConnect(self, response):
        logging.info("Server connected")
        print("Server connected: {0}".format(response.peer))

    def onOpen(self):
        print("WebSocket connection open.")
        self.sendMessage(u"Hello, world!".encode('utf8'))

    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {0} bytes".format(len(payload)))
        else:
            print("Text message received: {0}".format(payload.decode('utf8')))

    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {0}".format(reason))

if __name__ == '__main__':
    txaio.start_logging(level='debug')
    #print(parse_url("wss://echo.websocket.org"))
    factory = WebSocketClientFactory("wss://echo.websocket.org/")
    factory.protocol = MyClientProtocol
    loop = asyncio.get_event_loop()

    async def main():
        coro = loop.create_connection(factory, "echo.websocket.org", 443, ssl=True)
        print("running {}".format(coro))
        transport, proto = await coro
        print("proto {}".format(proto))
        await proto.done
    loop.run_until_complete(main())
    loop.close()