3

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?

Adil
  • 4,503
  • 10
  • 46
  • 63
Snigdha
  • 29
  • 1
  • 5
  • Don't use `threading`. Have a look at `IOLoop.add_timeout` and especially `tornado.ioloop.PeriodicCallback`. Don't forget to remove the callback when the connection is closed. – Thijs van Dien Oct 23 '13 at 16:56
  • Hi Thijs van Dien,Thanks but how to remove the callback? – Snigdha Oct 24 '13 at 12:13
  • I tried this def open(self): print 'new connection' main_loop=tornado.ioloop.IOLoop.instance() scheduler=tornado.ioloop.PeriodicCallback(self.msg('testing'),interval_ms,io_loop=main_loop) scheduler.start() main_loop.start() But am getting error : Traceback (most recent call last): File "/Library/Python/2.7/site-packages/tornado/ioloop.py", line 814, in _run self.callback() TypeError: 'NoneType' object is not callable ERROR:tornado.application:Error in periodic callback – Snigdha Oct 24 '13 at 12:22
  • You cannot supply arguments to the callback method; you need to pass it, not call it - see below for an example. – Thijs van Dien Oct 24 '13 at 16:14

3 Answers3

5

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()
Thijs van Dien
  • 6,516
  • 1
  • 29
  • 48
  • @user2911377 I strongly recommend you read the chapters on Asynchronous Web Programmming from Introduction to Tornado: http://www.amazon.com/Introduction-Tornado-Michael-Dory/dp/1449309070 – Thijs van Dien Oct 24 '13 at 16:36
  • How to write our own RestAPI in Python? – Snigdha Oct 28 '13 at 09:52
  • 1
    @Snigdha You're going way off-topic. REST API's are generally implemented as regular HTTP, not websockets. And regardless of that, one question (topic) per question. – Thijs van Dien Oct 28 '13 at 10:58
  • Can list be passed to self.write?I mean self.write(samplelist).Is this possible?I tried this am getting assertion error.Please help me – Snigdha Oct 31 '13 at 11:46
0

You are calling the function in stead of starting a timer. Do this:

threading.Timer(10, self.msg, args =('in timer',)).start()
User
  • 14,131
  • 2
  • 40
  • 59
  • I think using `threading` at all is inappropriate. Tornado is asynchronous and has its own facilities for executing a command on a schedule. – Thijs van Dien Oct 23 '13 at 16:54
  • Hi Thanks I tried this but When I closed the connection from client am getting error – Snigdha Oct 24 '13 at 12:24
0

could those examples help you

Tornado example

also this too Documentation tornado WS

Community
  • 1
  • 1
BlaShadow
  • 11,075
  • 7
  • 39
  • 60