繁体   English   中英

客户端连接后通过ws从其他类发送数据

[英]Send data from an other class through ws after client connected

我想在客户端连接后立即通过websocket发送数据。 数据位于Websocket处理程序之后的另一个位置。 我如何将数据发送给客户端?

服务器应保留循环和处理程序。 在连接器中,我连接到tcp套接字以从某些硬件中获取数据。 我希望一次打开6个Websocket。 数据作为流从TCP套接字流出。

server.py

import os
from tornado import web, websocket
import asyncio
import connector


class StaticFileHandler(web.RequestHandler):

    def set_default_headers(self):
        self.set_header("Access-Control-Allow-Origin", "*")

    def get(self):
        self.render('index.html')


class WSHandler(websocket.WebSocketHandler):
    def open(self):
        print('new connection')
        self.write_message("connected")

    def on_message(self, message):
        print('message received %s' % message)
        self.write_message("pong")

    def on_close(self):
        print('connection closed')


public_root = 'web_src'

handlers = [
    (r'/', StaticFileHandler),
    (r'/ws', WSHandler),
]

settings = dict(
    template_path = os.path.join(os.path.dirname(__file__), public_root),
    static_path = os.path.join(os.path.dirname(__file__), public_root),
    debug = True
)

app = web.Application(handlers, **settings)

sensorIP = "xxx.xxx.xxx.xxx"

if __name__ == "__main__":
    app.listen(8888)
    asyncio.ensure_future(connector.main_task(sensorIP))
    asyncio.get_event_loop().run_forever()

connector.py

import yaml
import asyncio


class RAMReceiver:
    def __init__(self, reader):
        self.reader = reader
        self.remote_data = None
        self.initParams = None

    async def work(self):
        i = 0
        while True:
            data = await self.reader.readuntil(b"\0")
            self.remote_data = yaml.load(data[:-1].decode("utf-8", 
            "backslashreplace"))

            # here i want to emit some data
            # send self.remote_data to websockets 

            if i == 0:
                i += 1
                self.initParams = self.remote_data

                # here i want to emit some data after open event is 
                # triggered
                # send self.initParams as soon as a client has connected


async def main_task(host):
    tasks = []
    (ram_reader,) = await asyncio.gather(asyncio.open_connection(host, 
    51000))
    receiver = RAMReceiver(ram_reader[0])
    tasks.append(receiver.work())

while True:
    await asyncio.gather(*tasks)

您可以使用Tornado的add_callback函数在websocket处理程序上调用方法来发送消息。

这是一个例子:

1.在您的websocket处理程序上创建一个其他方法,该方法将接收来自connector.py的消息并将其发送给已连接的客户端:

# server.py

class WSHandler(websocket.WebSocketHandler):

    # make it a classmethod so that 
    # it can be accessed directly
    # from class without `self`
    @classmethod 
    async def send_data(cls, data):
         # write your code for sending data to client

2.将当前正在运行的IOLoopWSHandler.send_dataconnector.py

# server.py

from tornado import ioloop

...

if __name__ == "__main__":
    ...
    io_loop = ioloop.IOLoop.current() # current IOLoop
    callback = WSHandler.send_data
    # pass io_loop and callback to main_task
    asyncio.ensure_future(connector.main_task(sensorIP, io_loop, callback))
    ...

3.然后在connector.py修改main_task函数,以接收io_loopcallback 然后将io_loop callbackRAMReceiver并进行callback

4.最后,使用io_loop.add_callback调用WSHandler.send_data

class RAMReceiver:
    def __init__(self, reader, io_loop, callback):
        ...
        self.io_loop = io_loop
        self.callback = callback

    async def work(self):
        ...
        data = "Some data"
        self.io_loop.add_callback(self.callback, data)
        ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM