【问题标题】:Either the websocket or the tornado goes down everytime.websocket 或龙卷风每次都会关闭。
【发布时间】:2016-02-24 11:43:10
【问题描述】:

我是异步编程的新手。我已经使用 python 3.5 asyncio 几天了。我想让服务器能够从 websocket 机器客户端 (GPS) 接收数据,并将 html 页面呈现为 websocket 服务器的浏览器客户端。我使用 websockets 在端口 8765 连接我的机器客户端和服务器。为了呈现网页,我在端口 8888 使用了 tornado(html 文件位于 ./views/index.html )。该代码仅适用于 websocket 服务器。当我添加龙卷风服务器时,代码表现得很奇怪,我不知道为什么。 asyncio 的使用一定有一些东西。如果我放置

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

就在之前

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

,websocket 服务器没有连接。如果我做相反的事情,龙卷风服务器就不会运行。

请帮助我,因为我是异步编程的新手。 server.py、index.html 和 client.py(机器客户端)如下所示。

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>

【问题讨论】:

    标签: python websocket tornado


    【解决方案1】:

    您一次只能运行一个事件循环(除非您为每个事件循环分配自己的线程,但这要复杂得多)。幸运的是,Tornado 和 asyncio 之间有一座桥梁,可以让它们共享同一个 IOLoop。

    在您的程序的早期(在任何与龙卷风相关的代码之前,如app = make_app()),这样做:

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

    不要打电话给IOLoop.current().start()。这会将所有使用 Tornado 的组件重定向到使用 asyncio 事件循环。

    【讨论】:

    • 非常感谢。有效。期待与更多的异步程序合作。 :)
    猜你喜欢
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多