Skip to content

Encapsulation the API to a synchronous one #485

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
galah92 opened this issue Oct 9, 2018 · 1 comment
Closed

Encapsulation the API to a synchronous one #485

galah92 opened this issue Oct 9, 2018 · 1 comment
Labels

Comments

@galah92
Copy link

galah92 commented Oct 9, 2018

Hi,

I'm trying to use this library and essentially export a synchronous API, and thus creating a library to be used from matlab.

Essentially, I want start(), stop(), send(), recv() functions, where queues will be used in order to make the send() & recv() sync.

My current code (simplified) is:

class WebsocketServer():

    def __init__(self):
        self._server = None
        self._clients = set()
        self._loop = None

    def start(self, port=1234):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        self._loop = loop
        start_server = websockets.serve(self._handle_client,
                                        host='localhost',
                                        port=port,
                                        loop=loop)
        self._server = loop.run_until_complete(start_server)

    def stop(self):
        if self._server:
            self._server.close()
            self._server = None
            self._clients.clear()

    async def _handle_client(self, client, path):
        try:
            self._clients.add(client)
            async for buffer in client:
                await self._handle_buffer(client, buffer)
        finally:
            self._clients.remove(client)

    async def _handle_buffer(self, client, buffer):
        print(buffer)
        await client.send(buffer)


def main():
    server = WebsocketServer()
    server.start()
    asyncio.get_event_loop().run_forever()


if __name__ == '__main__':
    main()

Running this directly (using main()) works well, but calling server = WebsocketServer(); server.start() does not.

I'm starting a new event loop because without calling run_forever() the server isn't able to accept connections, and with it the API client (the matlab) is blocked. This approach also doesn't work, and I can't seem to understand why.

I guess it's more of an asyncio question but it's heavily related to the library, hope you can help. Thanks!

@aaugustin
Copy link
Member

I'm not 100% sure how you want to use this, but I can't see how it would work without a thread running the event loop.

The server needs loop.run_forever() to be running in order to work correctly. I would start it in a background thread.

Look at call_soon_threadsafe() to communicate between your library and the background thread, else you'll have problems.

@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
Projects
None yet
Development

No branches or pull requests

2 participants