websocket

1. 单聊的实现

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

app = Flask(__name__)


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


user_dict = {}


@app.route("/chat/<name>")
def chat(name):
    user_socket = request.environ.get("wsgi.websocket")
    user_dict[name] = user_socket       # 把登陆到聊天室的用户放到一个字典中,name:obj

    while 1:
       try:
           msg = user_socket.receive()
           msg_dict = json.loads(msg)  # 把接收到的json反序列化

           for user in user_dict:
               if user == msg_dict.get("to_user"):  # 找到要收信的用户,发过去
                   user_dict[user].send(msg_dict.get("message"))
       except:
           user_dict.pop(name)
           return "good bye!"

if __name__ == '__main__':
    websocket = WSGIServer(("0.0.0.0", 8001), application=app, handler_class=WebSocketHandler)
    websocket.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">
    <title>Title</title>

</head>
<body>
<p>名字: <input type="text" id="name"></p>
<button onclick="open_chat()">join</button>

<p>to:<input type="text" id="to_user"></p>
<p>信息:<input type="text" id="send_message"></p>
<button onclick="send_message()">send</button>

<div id="chat"></div>

<script type="application/javascript">

    var ws = null;
    var name = null;
    function open_chat() {
        name = document.getElementById("name").value;
        ws = new WebSocket("ws://127.0.0.1:8001/chat/" + name);
        ws.onopen = function(){
           alert("欢迎"+name+"来到对骂平台!!!")
        };
        // 要写在创建websocket对象后面
        ws.onmessage = function (event_message) {
            var p = document.createElement("p");
            p.innerText = event_message.data;
            console.log(event_message);
            document.getElementById("chat").appendChild(p);
        };
          ws.onclose = function(){
            console.log("掉线了,兄嘚!!!");
        };
    }

    function send_message() {
        var send_message = document.getElementById("send_message").value;
        var to_user = document.getElementById("to_user").value;
        // 给服务器发的时候带着谁发的,发给谁,消息是什么
        var msg = {
            from_user:name,
            to_user:to_user,
           message:send_message
        };
        // 这是js中的object对象,要json序列化
        ws.send(JSON.stringify(msg))
    }

</script>

</body>
</html>
客户端

2. 群聊的实现

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

from flask import Flask, render_template, request

app = Flask(__name__)


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


user_list = []


@app.route("/my_ws")
def my_ws():
    user_socket = request.environ.get("wsgi.websocket")     # 拿到连接上的用户对象
    user_list.append(user_socket)        # 把所有连接上的用户对象都放在一个列表中
    while 1:
        try:
            msg = user_socket.receive()
        except WebSocketError:
            user_list.remove(user_socket)
            return "good bye!"
        for user in user_list:      # 遍历列表,把消息发给每一个人
            user.send(msg)



"""
request.environ 的数据
{
'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': 'LAPTOP-DNKA8ER5',
'SERVER_PORT': '8001',
'REQUEST_METHOD': 'GET',
'PATH_INFO': '/my_ws',
'QUERY_STRING': '',
'SERVER_PROTOCOL': 'HTTP/1.1',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '50061',
'HTTP_HOST': '127.0.0.1:8001',
'HTTP_CONNECTION': 'Upgrade',
'HTTP_PRAGMA': 'no-cache',
'HTTP_CACHE_CONTROL': 'no-cache',
'HTTP_UPGRADE': 'websocket',
'HTTP_ORIGIN': 'http://127.0.0.1:8001',
'HTTP_SEC_WEBSOCKET_VERSION': '13',
'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
'HTTP_ACCEPT_ENCODING': 'gzip,deflate, br', 
'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9,en;q=0.8',
'HTTP_COOKIE': 'csrftoken=a0jQx6LNfJty8IzXP5x9Z5QQaVkPncQ7OllFs3I7ZVhwXyAE5MHdVx9wNJu4dqdb; sessionid=vx6eyq4xqew1zkew0r8d0y48t9ngiz0d; session=54b644d8-fb51-4ecf-8761-f61a2fcaa077',
'HTTP_SEC_WEBSOCKET_KEY': '+bmrJihBAc6bMY5GaBfAWA==',
'HTTP_SEC_WEBSOCKET_EXTENSIONS': 'permessage-deflate; client_max_window_bits',
'wsgi.input': <gevent.pywsgi.Input object at 0x000002C52023FB28>,
'wsgi.input_terminated': True, 
'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x000001B392B91DB0>,
'werkzeug.request': <Request 'http://127.0.0.1:8001/my_ws' [GET]>}
"""

if __name__ == '__main__':
    # 实例化一个这个对象
    websocket = WSGIServer(("0.0.0.0", 8001), application=app, handler_class=WebSocketHandler)
    # 永久的开启这个对象
    websocket.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">
    <title>Title</title>

</head>
<body>


<input type="text" id="send_msg">
<button onclick="send_message()" >发送</button>

<div id="chat">
    <p>message</p>
</div>

<script type="application/javascript">

    var ws = new WebSocket("ws://127.0.0.1:8001/my_ws");
    ws.onmessage = function (event_message) {
        var p = document.createElement("p");
        p.innerText = event_message.data;
        console.log(event_message.data);
        document.getElementById("chat").appendChild(p)
    };
    function send_message() {
        var send_msg = document.getElementById("send_msg").value;
        ws.send(send_msg);
    }

</script>


</body>
</html>
客户端
原文地址:https://www.cnblogs.com/q767498226/p/10713611.html