python Tornado websockets how to send message ever

2020-06-12 04:57发布

问题:

I am trying to cobble together a test which allows websockets clients to connect to a Tornado server and I want the Tornado server to send out a message to all clients every X seconds.

The reason I am doing this is because wbesockets connections are being silently dropped somewhere and I am wondering of periodic "pings" sent by the websockets server will maintain the connection.

I'm afraid it's a pretty noobish question and the code below is rather a mess. I just don't have my head wrapped around Tornado and scope enough to make it work.

import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
import tornado.gen
import time
from tornado import gen

class WSHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        print 'http://mailapp.crowdwave.com/girlthumb.jpg'
        self.write_message("http://www.example.com/girlthumb.jpg")

    def on_message(self, message):
        print 'Incoming message:', message
        self.write_message("http://www.example.com/girlthumb.jpg")


    def on_close(self):
        print 'Connection was closed...'

@gen.engine
def f():
    yield gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 8)
    self.write_message("http://www.example.com/x.png")
    print 'x'

@gen.engine
def g():
     yield gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 4)
     self.write_message("http://www.example.com/y.jpg")
     print 'y'

application = tornado.web.Application([
    (r'/ws', WSHandler),
    ])

if __name__ == "__main__":
    tornado.ioloop.IOLoop.instance().add_callback(f)
    tornado.ioloop.IOLoop.instance().add_callback(g)
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

回答1:

Why don't you try write a scheduler inside it? :)

def schedule_func():
    #DO SOMETHING#

#milliseconds
interval_ms = 15
main_loop = tornado.ioloop.IOLoop.instance()
sched = tornado.ioloop.PeriodicCallback(schedule_func,interval_ms, io_loop = main_loop)
#start your period timer
sched.start()
#start your loop
main_loop.start()


回答2:

Found that the accepted answer for this is almost exactly what I want:

How to run functions outside websocket loop in python (tornado)

With a slight modification, the accepted answer at the above link continually sends out ping messages. Here is the mod:

Change:

def test(self):
    self.write_message("scheduled!")

to:

def test(self):
    self.write_message("scheduled!")
    tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(seconds=5), self.test)