WebSocket Server sending messages periodically in python

Snigdha picture Snigdha · Oct 23, 2013 · Viewed 7.8k times · Source

I have a tornado web server in python:

import tornado.httpserver
import tornado.websocket
import tornado.ioloop
from tornado.ioloop import IOLoop
import tornado.web
import time
import   threading
import sys
from datetime import datetime
from datetime import timedelta

def sample():
    print 'hiiiii'
    threading.Timer(10, sample).start()

class WSHandler(tornado.websocket.WebSocketHandler):

    def open(self):
        print 'new connection'

    def on_message(self, message):
        self.write_message(message)  
        self.msg('hellooooooo')
        print message

    def msg(self,message):
        self.write_message(message)
        threading.Timer(10, self.msg('in timer')).start()
        print 'in msg'+message
    def on_close(self):
        print 'connection closed'

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

if __name__ == "__main__":
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8888)
    interval_ms=120
    main_loop=tornado.ioloop.IOLoop.instance()
main_loop.start()

And the client is

<html>
<head>
<script> 

function fun(){

    alert("in fun()");

    var val=document.getElementById("txt");
    var ws = new WebSocket("ws://localhost:8888");

    ws.onopen = function(evt) { alert("Connection open ...");
    ws.send(val.value); };
    ws.onmessage = function(evt) {
         alert("from server: "+evt.data);
    }

    ws.onclose = function(evt) { 
        alert("Connection closed.");
    }
}

</script>

</head>
<body bgcolor="#FFFFFF">
    <input type="text" id="txt" />
    <button onClick="fun()">click</button>
</body>
</html>

I want to get the message periodically to the client. But when I try this I get this error: RunTimeError :Maximum Recursion Depth Exceeded. Please help me solve this issue. Also, how do we know what are the clients connected to the server?

Answer

Thijs van Dien picture Thijs van Dien · Oct 24, 2013

Here's a minimal example using the PeriodicCallback.

import tornado.httpserver
import tornado.websocket
import tornado.ioloop
from tornado.ioloop import PeriodicCallback
import tornado.web

class WSHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        self.callback = PeriodicCallback(self.send_hello, 120)
        self.callback.start()

    def send_hello(self):
        self.write_message('hello')

    def on_message(self, message):
        pass

    def on_close(self):
        self.callback.stop()

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

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