我正在尝试编写Tornado TCP + HTTP Server应用程序。
我的用例是一个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()
根据龙卷风文档,似乎可以将队列应用于协程,并且在这里我试图将其复制到两个不同的类中。是一个错误..我是龙卷风的新手,所以请忍受我愚蠢的问题.. >
答案 0 :(得分:0)
您有多种选择:
IndexHandler
发送请求,并且希望客户端等待直到消息在队列中,则可以将处理程序转换为协程。get_nowait()
方法。案例1的示例:
from tornado.queues import Queue
q = Queue()
class IndexHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
self.data_future = q.get()
data = yield self.data_future
self.render('index.html', data=data)
def on_connection_close(self):
# set an empty result on the future
# if connection is closed so that
# the messages don't get removed from
# the queue unnecessariliy for
# closed connections
self.msg_future.set_result(None)
案例2的示例:
from tornado.queues import Queue, QueueEmpty
q = Queue()
def get(self):
try:
data = q.get_nowait()
except QueueEmpty:
data = None
self.render(...)