flask 第五章 WebSocket GeventWebsocket 單聊羣聊 握手 解密 加密

1.WebSocketjavascript

首先咱們來回顧一下,咱們以前用socket學習過的項目有:css

  1.djangohtml

  2.flaskjava

  3.FTP - 文件服務web

HTTP - TCP (特色):django

  1.一次請求,一次響應,而後斷開json

  2.客戶端永遠處於主動狀態flask

  3.服務端永遠處於被動狀態安全

  4.HTTP請求是無狀態的 -- 在服務器不保存客戶端的信息服務器

  5.因爲HTTP請求是無狀態的,因此服務器沒法主動找到客戶端

   優勢 : 

    1.速度快 

    2.信息安全

    3.不是特別佔用資源

1.輪詢:

  客戶端不停的向服務端發送請求,服務端不停的向客戶端響應,直到客戶端拿到數據爲止.

  劣勢:

    1.服務端和客戶端雙端資源浪費

    2.帶寬資源佔用(帶寬 : 網絡鏈接時所能傳送的最大數據流速)

    3.不能保證數據的實時性

2. 長輪詢:

  客戶端向服務端發送一個請求,服務端保持這個請求,不返回值就不響應,必定時間後,服務器拋棄這個請求或者是返回. 客戶端收到請求後,當即再次發起保持鏈接.

在這裏咱們類比一個實例:

  你去傳達室問大爺有沒有快遞,大爺款待你喝茶(喝茶的時候就至關於保持鏈接),若是中途你想去廁所(去廁所就至關因而斷開了鏈接),回來以後繼續喝茶(再次創建保持鏈接).

  劣勢:

    1.相比於輪詢方式,長輪詢方式只是浪費了服務器的資源

    2.沒法保證是數據實時性

  優點:

    1.相比於輪詢方式,他節省了客戶端的資源

    2.保證數據有效

3.長鏈接

  永久的保持鏈接(如今咱們用的基本上都是長鏈接)

  劣勢:

      對服務器的CPU要求比較高

  優點:

    1.節省了大量的資源(客戶端和服務端的資源都節省了)

    2.數據實時有效性

    3.帶寬資源幾乎不佔用

WebSocket協議 : ws協議 ws://127.0.0.1 用JavaScript封裝客戶端

  三方 : geventWebsocket Flask

  web框架 : 用來進行Http請求的處理(握手)

4.單聊 

.py文件的代碼以下:

import json

from flask import Flask, render_template, request
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from geventwebsocket.websocket import WebSocket
from geventwebsocket.exceptions import WebSocketError

app = Flask(__name__)

user_socket_dict = {}


@app.route('/my_app')
def my_app():
    return render_template('myapp.html')


@app.route('/my_ws/<username>')
def my_ws(username):
    user_socket = request.environ.get( 'wsgi.websocket')  
    # 'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x00000206FCDC1528>,
    user_socket_dict[username] = user_socket  # type:WebSocket
    # print(user_socket_dict)
    while 1:
        try:
            # 阻塞等待消息數據
            msg = user_socket.receive()
            # 將接收到的消息反序列化成字典
            msg_dict = json.loads(msg)
            # print(msg)
            to_user = msg_dict.get('to_user')
            to_user_socket = user_socket_dict.get(to_user)
            to_user_socket.send(msg)
        except WebSocketError:
            user_socket_dict.pop(username)
            return '有個地方錯了'


if __name__ == '__main__':
    http_server = WSGIServer(('0.0.0.0', 9527), app, handler_class=WebSocketHandler)
    http_server.serve_forever()

myapp.html 文件代碼以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
你的名字:<input type="text" id="nkname">
<button onclick="open_chat()">登陸聊天室</button>
<p>發送至<input type="text" id="to_user"></p>
消息<input type="text" id="message">
<button onclick="send_msg()">發送</button>
<div id="chat_list">

</div>
</body>
<script type="application/javascript">
    var ws = null;

    function open_chat() {
        var nkname = document.getElementById('nkname').value;
        ws = new WebSocket("ws://127.0.0.1:9527/my_ws/" + nkname);
        ws.onopen = function () {
            alert('歡迎' + nkname + '登陸對罵平臺!!')
        };
        ws.onmessage = function (EventMessage) {
            var chat = JSON.parse(EventMessage.data);
            var p = document.createElement('p');
            p.style.cssText = 'width : 250px; text-align:left';
            p.innerText = chat.from_user + '-->' + chat.message;
            document.getElementById('chat_list').appendChild(p);
        };
        ws.onclose = function () {
            console.log('斷開鏈接了,啥狀況啊? 搞事情啊');
        };
    }

    function send_msg() {
        var message = document.getElementById('message').value;
        var from_user = document.getElementById('nkname').value;
        var to_user = document.getElementById('to_user').value;
        var send_str = {
            message: message,
            from_user: from_user,
            to_user: to_user
        };
        ws.send(JSON.stringify(send_str));
        var p = document.createElement('p');
        p.style.cssText = "width: 250px;text-align: right";
        p.innerText = send_str.message + "<-我";
        document.getElementById('chat_list').appendChild(p);
    }

</script>
</html>

5.羣聊

.py文件代碼以下: 

from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from geventwebsocket.websocket import WebSocket
from geventwebsocket.exceptions import WebSocketError

from flask import Flask,render_template,request

app = Flask(__name__)

user_socket_list = []

@app.route("/my_app")
def my_app():
    return render_template("my_app.html")

@app.route("/my_ws")
def my_ws():
    user_socket = request.environ.get("wsgi.websocket") 
    # type:WebSocket
    user_socket_list.append(user_socket)
    # print(len(user_socket_list),user_socket_list)
    while 1:
        try:
            msg = user_socket.receive() # 阻塞等待消息數據
        except WebSocketError:
            user_socket_list.remove(user_socket)
            return "good bye"
        for u in user_socket_list:
            if u == user_socket:
                continue
            try:
                u.send(msg)
            except :
                continue

if __name__ == '__main__':
    # app.run()
    http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler)
    http_serv.serve_forever()

myapp.html文件代碼以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <input type="text" id="message"><button onclick="send_message()">發送</button>
    <div id="chat_list">

    </div>
</body>
<script type="application/javascript">
    var ws = new WebSocket("ws://192.168.14.200:9527/my_ws");
    ws.onmessage = function (eventMessage) {
        // document.getElementById("chat_list").innerHTML += "<p>" + eventMessage.data + "</p>";
        var p = document.createElement("p");
        p.innerText = eventMessage.data;
        document.getElementById("chat_list").appendChild(p);
    };

    function send_message() {
        var message = document.getElementById("message").value;
        ws.send(message);
    }

</script>
</html>
相關文章
相關標籤/搜索