websocket.recv() never returns inside another event loop
<p>I am currently developing a <strong>server</strong> program in Python that uses the websockets and asyncio packages.</p>

<p>I got a basic script handling websockets working (Exhibit A). This script locks when waiting for input, which is not what I want.</p>

<p>The solution for this that I imagine is I can start two asynchronous tasks - one that handles inputs and one that handles outputs - and start them in a secondary event loop. I had to do some research about coroutines, and I came up with Exhibit B as a proof of concept for running two things simultaneously in an event loop.</p>

<p>Now what I'm stuck on is Exhibit C. When I attempted to use this in a practical scenario with the websockets package, I found that websocket.recv() never finishes (or the coroutine never un-pauses - I'm not sure what's going on exactly). In exhibit A it works fine, and I've determined that the coroutine definitely runs at least up until that point.</p>

<p>Any ideas?</p>

<p>Exhibit A:</p>

<pre><code>#!/usr/bin/python3

import asyncio
import websockets
import time

# This works great!
async def hello(websocket, path):
    while True:
        # This line waits for input from socket
        name = await websocket.recv()
        print("&lt; {}".format(name))

        # "echo... echo... echo... echo... echo..."
        greeting = ''.join(name + "... " for x in range(5))
        await websocket.send(greeting)
        print("&gt; {}".format(greeting))

        time.sleep(0.1);

start_server = websockets.serve(hello, '', 26231)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
</code></pre>

<p>Exhibit B:</p>

<pre><code>#!/usr/bin/python3
import asyncio
import time

class Thing:
    def __init__(self):
        pass
    async def test(self):
        for x in range(10):
            print("Hello"+str(x))
            await asyncio.sleep(0)
    def run(self):
        # Add the task to the event loop twice
        asyncio.ensure_future(self.test())
        asyncio.ensure_future(self.test())

t = Thing()
t.run()

loop = asyncio.get_event_loop();
loop.run_forever()
</code></pre>

<p>Exhibit C:</p>

<pre><code>#!/usr/bin/python3
import asyncio
import websockets
import time

class WebsocketRequest:
    def __init__(self, websocket):
        self.websocket = websocket

    # Works great
    async def handle_oputs(self):
        # This works fine - sends a message
        #  every 10 seconds to the client
        while True:
            print("sending...")
            await self.websocket.send("Hello")
            print("&gt; {}".format("Hello"))
            time.sleep(10)

    # Doesn't work
    async def handle_iputs(self):
        # This stops at the await and never receives
        #  any input from the client :/
        while True:
            try:
                print("receiving...")
                # This is the line that causes sadness
                data = await self.websocket.recv()
                print("&lt; {}".format(data))
            except:
                # This doesn't happen either
                print("Listener is dead")

    async def run(self):

        # This is the part where the coroutine for
        #  a client get split off into two of them
        #  to handle input and output separately.
        loop = asyncio.new_event_loop()

        asyncio.set_event_loop(loop)
        asyncio.ensure_future(self.handle_iputs())
        asyncio.ensure_future(self.handle_oputs())

        loop.run_forever()

class WebsocketServer:
    def __init__(self, address):
        self.ip = address[0]
        self.port = address[1]


    async def hello(self, websocket, path):
        req = WebsocketRequest(websocket)
        await req.run()

    def run(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        start_server = websockets.serve(self.hello, self.ip, self.port)

        asyncio.get_event_loop().run_until_complete(start_server)
        asyncio.get_event_loop().run_forever()
</code></pre>