WebSocket

轮询 长轮询 长连接

1. 轮询 Http (无状态请求连接)
	- 每秒钟发起至少100次, 请求收取消息
	- 客户端有一定的处理能力
	- 服务器有极快的处理速度

	缺点: 客户端服务器, 浪费资源严重, 宽带浪费
2. 长轮询 Http
	先去连接服务器, 不断开连接, 保持一定时间, 断开瞬间再次发起连接
	- 浪费服务器资源严重
	- 节省客户端资源
	- 相对实时性消息
3. 长连接 基于Http发起握手
	保持和服务器的长连接永不断来, 除非有一端主动发起断开请求
	- 发是发, 收是收, 互不影响
	- 在客户端和服务器上各有一个轮询
    - 双端分担压力
    - 消息及时性
    
	缺点: 占用连接资源, 占用网络资源

WebSocket

服务器主动给客户端发送消息 (web -> socket)
websocket 客户端与 websocket 服务器, 达成一个websocket协议

群聊 (group_chat)

视图:

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

app = Flask(__name__)

user_socket_list = []            # 存放每一个WebSocket(聊天用户)对象

@app.route('/conn_ws')
def websocket_func():
    user_socket = request.environ.get('wsgi.websocket') # type:WebSocket # 获取每一个对象
    user_socket_list.append(user_socket)

    while True:

        msg = user_socket.receive()
        print(msg)

        for u_socket in user_socket_list:
            u_socket.send(msg)

if __name__ == '__main__':
    http_server = WSGIServer(('0.0.0.0', 9090), app, handler_class=WebSocketHandler)
    http_server.serve_forever()  # 启动

1. request.environ  # 获取发来的请求对象
< geventwebsocket.websocket.WebSocket object at 0x00000135B14A1F50 >

2. handler_class=WebSocketHandler: 请求一进来, 如果不是http请求, 通过WebSocketHandler做处理
3. 在WSGIServer中加入了WebSocket的处理机制

前端状态码:
	# readyState: 1  # 已经开启了websocket连接
	# readyState: 3  # 开启了websocket, 但又断开连接
# 前端 (html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    
<input type="text" id="send_msg">
<button id="send_btn" onclick="send()">发送消息</button>
<p><div id="chat_list "></div></p>
</body>

<script type="application/javascript">
    var ws = new WebSocket('ws://192.168.11.51:9090/conn_ws');
    ws.onmessage = function (messageEvent) {
        console.log(messageEvent.data);
        var ptag = document.createElement("p");
        ptag.innerText = messageEvent.data;
        document.getElementById('chat_list').appendChild(ptag);
    };

    function send() {
        var send_msg = document.getElementById('send_msg').value;
        ws.send(send_msg);
    }

</script>
</html>

单聊 (private chat)

# 视图

import json

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

app = Flask(__name__)

user_socket_dict = {}

@app.route('/conn_ws/<user_nick>')
def websocket_func(user_nick):
    user_socket = request.environ.get('wsgi.websocket')  # type:WebSocket
    user_socket_dict[user_nick] = user_socket

    while True:
        msg = user_socket.receive()
        msg_dict = json.loads(msg)
        to_user = msg_dict.get('to_user')
        to_user_socket = user_socket_dict.get(to_user)
        to_user_socket.send(msg)

@app.route('/')
def index():
    return render_template('single_chat.html')


if __name__ == '__main__':
    http_server = WSGIServer(('0.0.0.0', 9090), app, handler_class=WebSocketHandler)
    http_server.serve_forever()  # 启动

# msg =  {from_user:"jason",to_user:"jake",message:"666"}
# 模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>   
    <input type="text" id="nick">
    <button onclick="login()">登陆聊天室</button>
</p>

发送给: <input type="text" id="to_user">消息: <input type="text" id="send_msg">
<button id="send_btn" onclick="send()">发送消息</button>

<div id="chat_list"> </div>

</body>
<script type="application/javascript">

    var ws = null;

    function login() {
        var nick = document.getElementById('nick').value;
        ws = new WebSocket('ws://192.168.11.51:9090/conn_ws/'+nick);

        ws.onmessage = function (messageEvent) {
            console.log(messageEvent.data);
            var ptag = document.createElement("p");

            var message = JSON.parse(messageEvent.data);

            ptag.innerText = message.from_user + " : " + message.message;
            document.getElementById('chat_list').appendChild(ptag);
        };
    }

    // 发送消息
    function send() {
        var message = document.getElementById('send_msg').value;
        var send_msg = {
          from_user: document.getElementById('nick').value,
          to_user: document.getElementById('to_user').value,
          message:message
        };
        var json_send_msg = JSON.stringify(send_msg);
        ws.send(json_send_msg);
    }

</script>
</html>
posted @ 2019-07-08 15:27  言值  阅读(235)  评论(0编辑  收藏  举报