用python定期发送消息的WebSocket服务器

用python定期发送消息的WebSocket服务器,python,websocket,tornado,periodic-task,Python,Websocket,Tornado,Periodic Task,我有一个python的tornado web服务器: 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 time

我有一个python的tornado web服务器:

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()
客户是

<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>

函数fun(){
警惕(“in fun()”);
var val=document.getElementById(“txt”);
var ws=newwebsocket(“ws://localhost:8888”);
ws.onopen=函数(evt){alert(“连接打开…”);
ws.send(val.value);};
ws.onmessage=函数(evt){
警报(“来自服务器:+evt.data”);
}
ws.onclose=函数(evt){
警报(“连接关闭”);
}
}
点击

我希望定期将消息发送给客户端。但当我尝试此操作时,会出现以下错误:
RunTimeError:超过最大递归深度。
请帮助我解决此问题。另外,我们如何知道哪些客户端连接到服务器?

您正在调用该函数,而不是启动计时器。这样做:

threading.Timer(10, self.msg, args =('in timer',)).start()

这些例子对你有帮助吗


这也是这里有一个使用
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()

我认为使用
线程
是不合适的。Tornado是异步的,它有自己的工具来按计划执行命令。您好,谢谢。我尝试了这个方法,但是当我关闭客户端的连接时,出现了错误。请不要使用
线程处理
。查看一下
IOLoop.add_timeout
,尤其是
tornado.IOLoop.PeriodicCallback
。不要忘记在连接关闭时删除回调。你好,Thijs van Dien,谢谢,但是如何删除回调?我尝试了这个def open(self):打印“新连接”main\u loop=tornado.ioloop.ioloop.instance()调度器=tornado.ioloop.PeriodicCallback(self.msg('testing'),interval\ms,io\u loop=main\u loop)调度器.start()main_loop.start()但我收到错误:Traceback(最近一次调用最后一次):File“/Library/Python/2.7/site packages/tornado/ioloop.py”,第814行,在_runself.callback()TypeError中:“NoneType”对象不可调用错误:tornado.application:定期回调中的错误您无法为回调方法提供参数;您需要传递它,而不是调用它-请参见下面的示例。@user2911377我强烈建议您阅读《Tornado简介:如何用Python编写我们自己的RestAPI》中有关异步Web编程的章节?@Snigdha您偏离了主题。RESTAPI通常作为常规HTTP实现,而不是WebSocket。不管怎样,每个问题都有一个问题(主题)。列表可以传递给self.write吗?我是说self.write(samplelist)。这可能吗?我尝试了这个,但发现断言错误。请帮助我