Either the websocket or the tornado goes down everytime.
Question: I am new to asynchronous programming. I have been using python 3.5 asyncio for
a few days. I wanted to make a server capable of receiving data from a
websocket machine client (GPS) as well as rendering a html page as the browser
client for the websocket server. I have used websockets for the connection
between my machine client and server at port 8765. For rendering the webpage I
have used tornado at port 8888 (The html file is at ./views/index.html ). The
code works fine for only the websocket server. When I added the tornado
server, the code behaved weird and I don't know why. There must be something
with the asyncio usage. If I place

    
    
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
    

just before

    
    
    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()
    

, the websocket server doesn't connect. If I do the reverse, the tornado
server doesn't run.

Please help me out as I am new to asynchronous programming. The server.py,
index.html and the client.py (machine clients) are given below.

server.py

    
    
    #!/usr/bin/env python
    
    import tornado.ioloop 
    import tornado.web 
    
    import asyncio
    import websockets
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render("./views/index.html", title = "GPS")
    
    def make_app():
        return tornado.web.Application([
            (r"/", MainHandler),
        ])
    
    clients = []
    
    async def hello(websocket, path):
        clients.append(websocket)
        while True:
            name = await websocket.recv()
            print("< {}".format(name))
    
            print(clients)
            greeting = "Hello {}!".format(name)
            for each in clients:
    
    
                await each.send(greeting)
                print("> {}".format(greeting))
    
    start_server = websockets.serve(hello, 'localhost', 8765)
    print("Listening on *8765")
    
    app = make_app()
    app.listen(8888)
    print("APP is listening on *8888")
    
    tornado.ioloop.IOLoop.current().start()
    asyncio.get_event_loop().run_until_complete(start_server)
    
    asyncio.get_event_loop().run_forever()
    

client.py

    
    
    #!/usr/bin/env python
    
    
    import serial
    import time 
    import asyncio
    import websockets
    
    ser =serial.Serial("/dev/tty.usbmodem1421", 9600, timeout=1)
    
    async def hello():
        async with websockets.connect('ws://localhost:8765') as websocket:
            while True:
                data = await retrieve()
                await websocket.send(data)
                print("> {}".format(data))
                greeting = await websocket.recv()
                print("< {}".format(data))
    
    
    async def retrieve():
            data = ser.readline()
            return data #return the location from your example
    
    asyncio.get_event_loop().run_until_complete(hello())
    asyncio.get_event_loop().run_forever()
    

./views/index.html

    
    
    <html>
       <head>
          <title>{{ title }}</title>
       </head>
       <body>
          <script>
                var ws = new WebSocket("ws://localhost:8765/"),
                messages = document.createElement('ul');
                ws.onopen = function(){
                  ws.send("Hello From Browser")
                }
                ws.onmessage = function (event) {
    
                var messages = document.getElementsByTagName('ul')[0],
                    message = document.createElement('li'),
                    content = document.createTextNode(event.data);
                message.appendChild(content);
                messages.appendChild(message);
            };
            document.body.appendChild(messages);
        </script>
    


Answer: You can only run one event loop at a time (unless you give each one its own
thread, but that's significantly more complicated). Fortunately, there's a
bridge between Tornado and asyncio to let them share the same IOLoop.

Early in your program (before any tornado-related code like `app =
make_app()`), do this:

    
    
    import tornado.platform.asyncio
    tornado.platform.asyncio.AsyncIOMainLoop().install()
    

and do not call `IOLoop.current().start()`. This will redirect all Tornado-
using components to use the asyncio event loop instead.

