手动重新加载网页 Tornado
Posted
技术标签:
【中文标题】手动重新加载网页 Tornado【英文标题】:Manually Reload webPage Tornado 【发布时间】:2015-10-28 14:51:27 【问题描述】:数据更新时是否可以重新加载页面?
import socket
import tornado.ioloop
import tornado.web
import tornado.gen
import tornado.ioloop
import tornado.iostream
import tornado.tcpserver
import os
import tornado.websocket
last_messages = dict()
class TcpClient(object):
client_id = 0
def __init__(self, stream):
super(TcpClient, self).__init__()
TcpClient.client_id += 1
self.id = 'Connection#%d' % TcpClient.client_id
self.stream = stream
self.stream.socket.setsockopt(
socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.stream.socket.setsockopt(
socket.IPPROTO_TCP, socket.SO_KEEPALIVE, 1)
self.stream.set_close_callback(self.on_disconnect)
@tornado.gen.coroutine
def on_disconnect(self):
self.log("disconnected")
yield []
@tornado.gen.coroutine
def dispatch_client(self):
try:
while True:
line = yield self.stream.read_until(b'\n')
text_line = line.decode('utf-8').strip()
last_messages[self.id] = text_line
# UPDATE GUI, webpage HERE
self.log('got |%s|' % text_line)
except tornado.iostream.StreamClosedError:
pass
@tornado.gen.coroutine
def on_connect(self):
raddr = 'closed'
try:
raddr = '%s:%d' % self.stream.socket.getpeername()
except Exception:
pass
self.log('new, %s' % raddr)
yield self.dispatch_client()
def log(self, msg, *args, **kwargs):
print('[%s] %s' % (self.id, msg.format(*args, **kwargs)))
class TcpServer(tornado.tcpserver.TCPServer):
@tornado.gen.coroutine
def handle_stream(self, stream, address):
connection = TcpClient(stream)
yield connection.on_connect()
class LastMessagesHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
self.render(
'template.html',
sources=last_messages
)
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def on_message(self, message):
print message
self.write(last_messages)
def main():
tcp = TcpServer()
tcp.listen(8008)
print('tcp://localhost:8008')
settings = dict(
template_path=os.path.join(os.path.dirname(__file__), 'templates'),
static_path=os.path.join(os.path.dirname(__file__), 'static'),
debug=True,
)
app = tornado.web.Application(
[
(r'/', LastMessagesHandler),
(r'/ws', WebSocketHandler)
],
**settings
)
app.listen(8009)
print('http://localhost:8009')
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
这是模板.html
<html>
<head>
<title>TCP server</title>
</head>
<body>
<title>Tornado WebSockets</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
jQuery(function($)
if (!("WebSocket" in window))
alert("Your browser does not support web sockets");
else
setup();
function setup()
var host = "ws://localhost:8008/ws";
var socket = new WebSocket(host);
// event handlers for websocket
if(socket)
socket.onopen = function()
//alert("connection opened....");
socket.onmessage = function(msg)
showServerResponse(msg.data);
/*socket.onclose = function()
//alert("connection closed....");
showServerResponse("The connection has been closed.");
*/
else
console.log("invalid socket");
function showServerResponse(txt)
var p = document.createElement('p');
p.innerHTML = txt;
document.getElementById('output').appendChild(p);
);
</script>
<div>
<ul id="output">
% for key, value in sources.iteritems() %
<ul> key | value </ul>
% end %
</ul>
</div>
</body>
</html>
每当 last_messages 更改时,我都需要更新 Client(webpage)(smth 从 dict 中删除,smth 已添加到 dict 中)。我不能使用 tornado.websocket 做到这一点。能否请你帮忙?从套接字读取行后,我需要更新 gui(您可以在我需要更新网页的代码中找到注释:# UPDATE GUI,webpage HERE)。所以套接字仍然可以打开(我们正在继续阅读行),但必须更新 gui。有可能吗?
【问题讨论】:
【参考方案1】:如果您真的想重新加载页面,那么您可以在 javascript 中发起对 window.location.reload()
的调用。
但是,这会从客户端关闭 WebSocket 连接。
如果你只是想更新 DOM (GUI),那么在客户端监听传入的消息并进行相应的更新。
要观察和跟踪数据更改,您可以使用 JavaScript 自己进行,如果您仅在现代 Chrome 上运行,则可以使用 Object.observe
,或者使用 polyfill,或者使用现有工具,例如 Backbone.js。
如果你选择后者,我也可以推荐一个tool to help you with working with WebSockets and Backbone。
免责声明:我是 Backbone.WS 的作者。
【讨论】:
以上是关于手动重新加载网页 Tornado的主要内容,如果未能解决你的问题,请参考以下文章
Android WebView - 在不重新加载的情况下设置 HTML
为啥手动重用的 UITableViewCell 在重新加载行时会消失?