【发布时间】:2019-06-20 15:12:24
【问题描述】:
我正在尝试编写 Tornado TCP + HTTP 服务器应用程序。
我的用例是 Tornado TCP + HTTP Server 应用程序,它接受来自 TCP 客户端的数据并传递数据以将其显示在托管在 HTTP 服务器上的网页上。
这是我的龙卷风服务器代码:
#!/usr/bin/env python
import os.path
import tornado.httpserver
import tornado.web
import logging
from tornado.ioloop import IOLoop
from tornado import gen
from tornado.iostream import StreamClosedError
from tornado.tcpserver import TCPServer
from tornado.options import options, define
define("port", default=6642, help="TCP port to listen on")
logger = logging.getLogger(__name__)
test = {}
class IndexHandler(tornado.web.RequestHandler):
def get(self):
global test
self.render('index.html', test=test)
class EchoServer(TCPServer):
@gen.coroutine
def handle_stream(self, stream, address):
global test
while True:
try:
test = yield stream.read_until("\n")
logger.info("Received bytes: %s", test)
except StreamClosedError:
logger.warning("Lost client at host %s", address[0])
break
except Exception as e:
print(e)
if __name__ == "__main__":
options.parse_command_line()
app = tornado.web.Application( handlers=[
(r'/', IndexHandler)],
static_path=os.path.join(os.path.dirname(__file__), "static"),
template_path=os.path.join(os.path.dirname(__file__), "templates"))
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
server = EchoServer()
server.listen(6641)
logger.info("Listening on TCP port %d",6641)
IOLoop.current().start()
这里是python客户端代码:
# echo_client.py
import socket
import time
counter = 0
host = '192.168.43.59'
port = 6641 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
s.sendall("s\n")
counter = counter + 1
time.sleep(5)
我想将从 TCP 客户端应用程序接收到的数据传递给变量“test”到渲染模板以显示在 index.html 网页中,但我没有显示任何数据。
我正在使用全局变量概念但没有成功,因为无法将更新后的“测试”变量传递给 index.html 页面。
如果有人能阐明在不同的类或处理程序中使用通用变量会帮助我。
我使用的Javascript文件是这样的:
/* test.js */
var test = ""
function set_test(val)
{
test=val
}
function show_test()
{
alert(test);
}
使用的 HTML 模板是这样的:
<!DOCTYPE html>
<html>
<meta http-equiv="refresh" content="30" />
<head>
<title>Test</title>
<script src="{{ static_url('scripts/test.js') }}"
type="application/javascript"></script>
</head>
<body>
<input type="button" onclick="show_test()" value="alert" />
<script type="application/javascript">
set_test("{{test}}");
</script>
</body>
</html>
嗨,xyres,
感谢您的自发回复。我浏览了您提供的链接,浏览后我明白 q.get() 和 q.put() 可用于存储和检索数据,如您所说。但是我无法在以以下方式修改龙卷风服务器代码后,我无法从 TCP 客户端接收数据,在此之前我至少可以从 TCP 客户端获取数据。你能告诉我我犯了什么错误吗?队列实现
这是我的龙卷风服务器代码:
#!/usr/bin/env python
import os.path
import tornado.httpserver
import tornado.web
import logging
from tornado.ioloop import IOLoop
from tornado import gen
from tornado.iostream import StreamClosedError
from tornado.tcpserver import TCPServer
from tornado.options import options, define
define("port", default=6642, help="TCP port to listen on")
logger = logging.getLogger(__name__)
#test = {}
q = Queue(maxsize=2)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
#global test
test = yield q.get
self.render('index.html', test=test)
class EchoServer(TCPServer):
@gen.coroutine
def handle_stream(self, stream, address):
#global test
yield q.put(test)
yield q.join()
while True:
try:
test = yield stream.read_until("\n")
logger.info("Received bytes: %s", test)
except StreamClosedError:
logger.warning("Lost client at host %s", address[0])
break
except Exception as e:
print(e)
if __name__ == "__main__":
options.parse_command_line()
app = tornado.web.Application( handlers=[
(r'/', IndexHandler)],
static_path=os.path.join(os.path.dirname(__file__), "static"),
template_path=os.path.join(os.path.dirname(__file__), "templates"))
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
server = EchoServer()
server.listen(6641)
logger.info("Listening on TCP port %d",6641)
IOLoop.current().start()
根据龙卷风文档,似乎队列可以应用于协程,在这里我试图将相同的复制到两个不同的类。这是一个错误..我是龙卷风的新手,所以请承担我的愚蠢问题..
【问题讨论】:
-
使用 Tornado 队列:tornadoweb.org/en/stable/queues.html。将接收到的数据放入队列并在您的请求处理程序中检索它,然后呈现模板。
-
根据龙卷风文档,队列似乎可以应用于协程,在这里我试图将相同的复制到两个不同的类。这是一个错误..我是龙卷风的新手,所以请忍受我的愚蠢问题..
-
你可以让你的
get处理程序成为协程。您使用的是哪个 Python 版本? -
嗨 xyres,我正在使用 python 2.7.13