Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python Tornado websockets how to send message every X seconds?

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()
like image 984
Duke Dougal Avatar asked Jul 04 '13 09:07

Duke Dougal


People also ask

Is Python good for WebSockets?

The communication can be sent either way at any time during the lifetime of the WebSocket connection. The client and the server are continuously connected — data can be sent to the clients all the time, without any need to request it. It's fairly easy to work with WebSockets in Python.

What is Tornado WebSocket?

websocket — Bidirectional communication to the browser. Implementation of the WebSocket protocol. WebSockets allow for bidirectional communication between the browser and server.

How does Python connect to WebSockets?

WebSocket Client with PythonCreate a new File “client.py” and import the packages as we did in our server code. Now let's create a Python asynchronous function (also called coroutine). async def test(): We will use the connect function from the WebSockets module to build a WebSocket client connection.


2 Answers

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()
like image 53
Natsume Avatar answered Sep 20 '22 17:09

Natsume


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)
like image 24
Duke Dougal Avatar answered Sep 17 '22 17:09

Duke Dougal