python tornado websocket

本文参考自
https://blog.csdn.net/moshowgame/article/details/85245944

主网站启动代码

#完整打分流程V2
import os
import os.path 

import sys

# sys.path.apend()
#解决yolov5的反序列化问题 start
import os,sys
root_path = os.getcwd()
sys.path.insert(0,root_path+"/yolov5")
#解决yolov5的反序列化问题 end
 

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.autoreload
from ApiRouter import GloabelRouter

import cv2 
import json 
 
import uuid
import base64
import ssl
 
# 导入加载业务逻辑部分, 每个handlers 都一定需要导入 start
from handlers import Auth
from handlers import OnlineRecognition,OnlineRecognitionYolo5,XiuZheng
from handlers import DatasetManage, AutoGrab
from handlers import TrainYoloV5,TrainMaskRcnn,TrainPaddlex,TrainPaddlexUnet
from handlers import WCMSAPI
from handlers import Index # inde必须放在最后否则返回 405 因为Index 的用的是通配符 (.*) 


# 导入加载业务逻辑部分, 每个handlers 都一定需要导入  end

from tornado.options import define, options 

# windows 系统下 tornado 使用 使用 SelectorEventLoop 解决一个bug start
import platform
if platform.system() == "Windows":
    import asyncio
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
# windows 系统下 tornado 使用 使用 SelectorEventLoop 解决一个bug  end


# print(context.options)
# 定义端口用于指定HTTP服务监听的端口
# 如果命令行中带有port同名参数则会称为全局tornado.options的属性,若没有则使用define定义。
define("port", type=int, default=443, help="run on the given port")
# 调试模式
define("debug", type=bool, default=True, help="debug mode")



static_path = os.path.join(os.path.dirname(__file__), 'static')
static_path = static_path.replace("\\","/")

chainpath =  os.getcwd()+ "/https/ai.**.com_chain.crt"
crtpath =  os.getcwd()+ "/https/ai.**.com_public.crt"
keypath =  os.getcwd()+ "/https/ai.**.com.key"
#print(crtpath,keypath)
if __name__ == '__main__':
    tornado.options.parse_command_line()
    settings = {
    
    
        'cookie_secret': base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes)
    }
    # 老式方式增加websocket
    mhandlers = [
        (r"/Log", TrainPaddlexUnet.LogHandler),
        # (r"/TestThread", TrainPaddlexUnet.HasBlockTaskHandler)
        
    ]
    # 新方式增加函数形式的api接口
    for x in GloabelRouter.handlers:
        mhandlers.append(x)
     
    app = tornado.web.Application(
         
        handlers = mhandlers,
        **settings,
        # handlers=[ 
        #     (r'/', OnlineRecognition.OnlineRecognitionHandler), 
        #     (r'/OnlineRecognition', OnlineRecognition.OnlineRecognitionHandler), 
        #     (r'/OnlineRecognitionYolo5', OnlineRecognitionYolo5.OnlineRecognitionYolo5Handler), 
        #     (r'/XiuZheng', XiuZheng.XiuZhengHandler),#修整AI算法的识别名称
        #     (r'/api/DatasetManage', DatasetManage.DatasetManageHandler),#
        #     (r'/api/auth/login', Auth.LoginHandler),#
        #     (r'/api/auth/logout', Auth.LogoutHandler),#
        #     (r'/api/user/info', Auth.UserInfoHandler),#
            
        #  ],
        template_path=os.path.join(os.path.dirname(__file__), "templates"),
        # template_path = os.path.dirname(__file__), # 定位到根目录方便定位index.html 文件
        settings = {
    
     'static_path' : static_path ,'debug' : True, "compiled_template_cache":False },
        static_path =static_path
    )

    ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH, cafile=chainpath)
    # ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) #这种是强制使用TLSV1.2协议
    ssl_ctx.verify_mode = ssl.CERT_NONE
    ssl_ctx.check_hostname = False
    ssl_ctx.load_cert_chain(crtpath, keypath)

    http_server = tornado.httpserver.HTTPServer(app,
        ssl_options = ssl_ctx
        # ssl_options={
    
    
        #    "certfile": crtpath,
        #    "keyfile": keypath
        # }
        )
    print("web https 服务正在监听",options.port)
    http_server.listen(options.port)
    print("web https 服务已启动...")

    #8181 再起一个服务器
    http_server2 = tornado.httpserver.HTTPServer(app)
    print("web http 服务正在监听",8181)
    http_server2.listen(8181)
    print("web http 服务已启动...")
    
    # tornado.ioloop.IOLoop.instance().start()
    instance = tornado.ioloop.IOLoop.instance()
    tornado.autoreload.start(5)
    instance.start()
  

WebSocket后台代码

 
class  LogHandler(WebSocketHandler):

    users = set()  # 用来存放在线用户的容器

    # 对外公开的静态方法, 用来发生信息到客户端
    @staticmethod
    def sendInfoMsgToWebClient(msg):
         for u in LogHandler.users:  # 向已在线用户发送消息
            u.write_message(msg)

    @staticmethod
    def sendErrorMsgToWebClient(msg):
         for u in UNet_TrainLogHandler.users:  # 向已在线用户发送消息
            u.write_message(msg)

    def open(self):
        self.users.add(self)  # 建立连接后添加用户到容器中
        for u in self.users:  # 向已在线用户发送消息
            u.write_message(u"[%s]-[%s]-进入聊天室" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))

    def on_message(self, message):
        for u in self.users:  # 向在线用户广播消息
            u.write_message(u"[%s]-[%s]-说:%s" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), message))

    def on_close(self):
        self.users.remove(self) # 用户关闭连接后从容器中移除用户
        for u in self.users:
            u.write_message(u"[%s]-[%s]-离开聊天室" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))

    def check_origin(self, origin):
        return True  # 允许WebSocket的跨域请求

前端代码,可以独立运行.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>聊天室</title>
</head>
<body>
    <div id="contents" style="height:500px;overflow:auto;"></div>
    <div>
        <textarea id="msg"></textarea>
        <a href="javascript:;" onclick="sendMsg()">发送</a>
    </div>
<!-- jQuery -->
<script src="https://cdn.staticfile.org/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
        var ws = new WebSocket("ws://127.0.0.1:8181/Log");
        ws.onmessage = function(e) {
     
     
            $("#contents").append("<p>" + e.data + "</p>");
        }
        function sendMsg() {
     
     
            var msg = $("#msg").val();
            ws.send(msg);
            $("#msg").val("");
        }
    </script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/phker/article/details/110180794