zoukankan      html  css  js  c++  java
  • Websocket

    flask中的socket

    需要将run,wsgi替换成websocket

    群聊

    # 不需要记住 但是要知道是什么模块驱使Flask 支持Websocket
    # gevent-websocket
    # 以下代码 和 gevent-websocket 使用方式 请记录在案
    from geventwebsocket.handler import WebSocketHandler
    from geventwebsocket.server import WSGIServer
    from geventwebsocket.websocket import WebSocket  # 语法提示
    
    from flask import Flask, request, render_template
    app = Flask(__name__)
    
    socket_list = []
    
    @app.route("/ws")
    def ws():
        sock = request.environ.get("wsgi.websocket")  # type:WebSocket
        socket_list.append(sock)
        print(socket_list)
        # 1 : 连接打开
        # 2 : 客户端主动关闭连接
        # 3 : 连接关闭 由服务器发起
        # 0 : 连接中。。。。。。
        while 1:
            try:
                msg = sock.receive()  # hello
            except:
                socket_list.remove(sock)
                break
            for so in socket_list:
                if so == sock:
                    continue
                try:
                    so.send(msg)
                except:
                    continue
    
        return "200OK"
    
        # return "200 OK"
    
    
    @app.route("/")
    def index():
        return render_template("ws_client.html")
    
    
    if __name__ == '__main__':
        # app.run()
        http_serv = WSGIServer(("0.0.0.0", 9527), app, handler_class=WebSocketHandler)  # environment
        http_serv.serve_forever()
    """
    {'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6', 'SCRIPT_NAME': '', 'wsgi.version': (1, 0), 'wsgi.multithread': False, 'wsgi.multiprocess': False, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'SERVER_NAME': 'DESKTOP-U8U37NO', 'SERVER_PORT': '9527', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/ws', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '56107', 'HTTP_HOST': '127.0.0.1:9527', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'wsgi.input': <gevent.pywsgi.Input object at 0x0000021596BF3B28>, 'wsgi.input_terminated': True, 'werkzeug.request': <Request 'http://127.0.0.1:9527/ws' [GET]>}
    """
    
    """
    {'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6', 'SCRIPT_NAME': '', 'wsgi.version': (1, 0), 'wsgi.multithread': False, 'wsgi.multiprocess': False, 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'SERVER_NAME': 'DESKTOP-U8U37NO', 'SERVER_PORT': '9527', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/ws', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '56249', 'HTTP_HOST': '127.0.0.1:9527', 'HTTP_CONNECTION': 'Upgrade', 'HTTP_PRAGMA': 'no-cache', 'HTTP_CACHE_CONTROL': 'no-cache', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', 'HTTP_UPGRADE': 'websocket', 'HTTP_ORIGIN': 'http://localhost:63342', 'HTTP_SEC_WEBSOCKET_VERSION': '13', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'HTTP_COOKIE': 'session=a11311f1-7927-4879-a8f5-04dbb6535410', 'HTTP_SEC_WEBSOCKET_KEY': '71CDvLfOHw8dkO9SiEGMjg==', 'HTTP_SEC_WEBSOCKET_EXTENSIONS': 'permessage-deflate; client_max_window_bits', 'wsgi.input': <gevent.pywsgi.Input object at 0x000002DFB6C93CA8>, 'wsgi.input_terminated': True, 'wsgi.websocket_version': '13', 'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x000002DFB6CC4660>, 'werkzeug.request': <Request 'http://127.0.0.1:9527/ws' [GET]>}
    """
    注释
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
      <title>Bootstrap 101 Template</title>
      <!-- Bootstrap -->
    </head>
    <body>
    <h1>你好,世界!</h1>
    <input type="text" id="text"> <button id="send">点击发送消息</button>
    <div id="content_list">
    
    </div>
    </body>
    <script type="application/javascript">
      var ws = new WebSocket("ws://192.168.14.26:9527/ws");
      // 回调函数
      // onopen websocket连接建立完成 status == 1
      // ws.onopen = function () {
      //     ws.send("Hello");
      // };
      // onmessage websocket 接收到消息时 执行
      ws.onmessage = function (eventMessage) {
          var s = eventMessage.data;
          var p = document.createElement("p");
          p.innerText = s;
          document.getElementById("content_list").appendChild(p);
      };
    
      // ws.onclose
    
      // ws.send("123");
    
      document.getElementById("send").addEventListener("onclick",function () {
          var st = document.getElementById("text").value();
          ws.send(st);
      })
    </script>
    </html>
    ws_client

    点对点

    import json
    
    from geventwebsocket.handler import WebSocketHandler # ws 协议请求处理
    from geventwebsocket.server import WSGIServer # 替换Flask 原有的WSGI
    from geventwebsocket.websocket import WebSocket # 语法提示
    
    from flask import Flask, request, render_template
    
    app = Flask(__name__)
    
    socket_dict = {}
    
    @app.route("/ws/<username>")
    def ws(username):
        sock = request.environ.get("wsgi.websocket",None) # type:WebSocket
        # 1.不是WS协议上来的请求 None
        # 2.WS协议认证失败 None
        if not sock :
            return "请使用WS协议连接"
    
        # if socket_dict.get(username).closed:
        #     return "已经登陆"
    
        socket_dict[username] = sock
        print(len(socket_dict),socket_dict)
    
        while True:
            msg = sock.receive()
            print(type(msg),msg)
            msg_dict = json.loads(msg)
            recv = msg_dict.get("recv")
            recv_sock = socket_dict.get(recv)
            recv_sock.send(msg)
    
    
    @app.route("/")
    def index():
        return render_template("ws_client_2.html")
    
    if __name__ == '__main__':
        http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler)
        http_serv.serve_forever()
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
      <title>Bootstrap 101 Template</title>
      <!-- Bootstrap -->
    </head>
    <body>
    <h1>你好,世界!</h1>
    你的名字:<input type="text" id="username"><button id="createws">登录聊天室</button>
    <p><input type="text" id="recv">发送<input type="text" id="text">内容 <button id="send">点击发送消息</button></p>
    <div id="content_list">
    
    </div>
    </body>
    <script type="application/javascript">
      var ws = null;
      document.getElementById("createws").onclick = function () {
          var username = document.getElementById("username").value;
          ws = new WebSocket("ws://192.168.14.26:9527/ws/"+username);
          ws.onopen = function () {
              alert("欢迎进入九聊");
          };
          ws.onmessage = function (eventMessage) {
              var msg = JSON.parse(eventMessage.data);
              console.log(msg);
              var p = document.createElement("p");
              p.innerText = msg.sender + " : " + msg.msg;
              document.getElementById("content_list").appendChild(p);
          };
      };
    
    
    
      // 回调函数
      // onopen websocket连接建立完成 status == 1
      // ws.onopen = function () {
      //     ws.send("Hello");
      // };
      // onmessage websocket 接收到消息时 执行
    
    
      // ws.onclose
    
      // ws.send("123");
    
      document.getElementById("send").onclick = function () {
          var recv = document.getElementById("recv").value;
          var msg = document.getElementById("text").value;
          var sender = document.getElementById("username").value;
    
          var send_msg = {
              "sender":sender,
              "recv": recv,
              "msg":msg
          };
          console.log(send_msg);
    
          ws.send(JSON.stringify(send_msg));
      };
    </script>
    </html>
    ws_client_2
  • 相关阅读:
    memwatch内存泄露检测工具
    JavasSript实现秒转换为“天时分秒”控件和TDD测试方法应用
    字符编码转换笔记
    AjaxFileUpload 方法与原理分析
    Lua Rings库介绍
    Virtualbox+UbuntuServer+Xshell搭建Linux开发环境
    HTTP下载文件名称编码说明
    lua metatable 和 _index 实验
    前向后瞻正则表达式及其JS例子
    浏览器浏览记忆(history)几则技巧记录
  • 原文地址:https://www.cnblogs.com/Pythonzrq/p/13259887.html
Copyright © 2011-2022 走看看