tornado==6.1 # 比之更新的版本会报错
1、多线程启动tornado,创建server.py
import sys
import tornado
import typing
from tornado import escape
from tornado import httputil
from typing import List, Tuple, Optional, Callable, Any, Dict
from types import TracebackType
if typing.TYPE_CHECKING:
from typing import Type # noqa: F401
from wsgiref.types import WSGIApplication as WSGIAppType # noqa: F401
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from main import app
# 多线程启动tornado
class WSGIContainer_With_Thread(WSGIContainer):
@tornado.gen.coroutine
def __call__(self, request):
data = {} # type: Dict[str, Any]
response = [] # type: List[bytes]
def start_response(
status: str,
headers: List[Tuple[str, str]],
exc_info: Optional[
Tuple[
"Optional[Type[BaseException]]",
Optional[BaseException],
Optional[TracebackType],
]
] = None,
) -> Callable[[bytes], Any]:
data["status"] = status
data["headers"] = headers
return response.append
loop = tornado.ioloop.IOLoop.instance()
app_response = yield loop.run_in_executor(None, self.wsgi_application, WSGIContainer.environ(request),
start_response)
# app_response = self.wsgi_application(
# WSGIContainer.environ(request), start_response
# )
try:
response.extend(app_response)
body = b"".join(response)
finally:
if hasattr(app_response, "close"):
app_response.close() # type: ignore
if not data:
raise Exception("WSGI app did not call start_response")
status_code_str, reason = data["status"].split(" ", 1)
status_code = int(status_code_str)
headers = data["headers"] # type: List[Tuple[str, str]]
header_set = set(k.lower() for (k, v) in headers)
body = escape.utf8(body)
if status_code != 304:
if "content-length" not in header_set:
headers.append(("Content-Length", str(len(body))))
if "content-type" not in header_set:
headers.append(("Content-Type", "text/html; charset=UTF-8"))
if "server" not in header_set:
headers.append(("Server", "TornadoServer/%s" % tornado.version))
start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason)
header_obj = httputil.HTTPHeaders()
for key, value in headers:
header_obj.add(key, value)
assert request.connection is not None
request.connection.write_headers(start_line, header_obj, chunk=body)
request.connection.finish()
self._log(status_code, request)
# http_server = HTTPServer(WSGIContainer(app))
http_server = HTTPServer(WSGIContainer_With_Thread(app)) # flask app
http_server.listen(6000)) # flask默认的端口
IOLoop.instance().start()
2、启动设置成Windows服务
1)cmd脚本(.bat文件)
@python.exe D:\项目路劲\server.py %*
@pause
2)使用srvany注册服务(https://wwr.lanzoui.com/iaC6Hubrukd)
srvany.exe是Microsoft Windows Resource Kits工具集的一个实用小工具,用于将EXE程序作为Windows服务运行。srvany是其注册程序的服务外壳,我们可以通过它让我们的程序以SYSTEM账户启动,或者实现随机器启动而自启动,也可以隐藏不必要的窗口,比如说控制台窗口等等。
配置: 新建一个自建服务,配置上上面bat的脚本。启动方式可以设置为自动启动或者手动启动。
启动和终止程序的话,直接用这个工具找到我们配置好的,启动或者终止即可。