flask的使用 05 基于websocket搭建网页聊天室

flask+websocket 实现聊天(单聊,群聊)

实施步骤

1先下载依赖

pip install flask gevent gevent-websocket

2新建flask项目,注意要点,ws协议非常不好测试,可以新建一个html页面


然后在浏览器console界面输入ws

输出:(状态说明:)

readyState: 1 说明已经连接上

readyState: 3 说明连接之前连接上了 但是现在又关闭了,判断是后端的问题(是否死循环等待)

WebSocket {url: "ws://192.168.15.42:5000/msg", readyState: 1, bufferedAmount: 0, onopen: null, onerror: null, …}binaryType: "blob"bufferedAmount: 0extensions: ""onclose: nullonerror: nullonmessage: nullonopen: nullprotocol: ""readyState: 1url: "ws://192.168.15.42:5000/msg"__proto__: WebSocket

3编写前端

gevent-websocket

gevent-websocket使用

1.什么是websocket;

2.gevent-websocket介绍;

3.编程思路介绍;

4.编程实现。

web socket

1.WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket通讯协议于2011年被IETF定为标准RFC 6455,WebSocketAPI被W3C定为标准;

2.在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送;

3.现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP request的header是非常长的,里面包含的数据可能只是一个很小的值,这样会占用很多的带宽和服务器资源;

4.而比较新的技术去做轮询的效果是Comet,使用了AJAX。但这种技术虽然可达到双向通信,但依然需要发出请求,而且在Comet中,普遍采用了长链接,这也会大量消耗服务器带宽和资源;

5.面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。

web socket优点

1.服务器与客户端之间交换的数据包档头很小,大概只有2字节;

2.服务器可以主动传送数据给客户端。

gevent-websocket

1.是使用gevent封装的websocket库;

2.可以很方便和其他网络框架结合。

实例思路

1.使用WebSocketHandler与pywsgi.WSGIServer结合;

2.建立连接后,服务器便每隔一段时间推送消息给浏览器,浏览器收到消息便打印出来;

3.html代码

Minimal websocket application

Test.py

import json
import random
from gevent import pywsgi, sleep
from geventwebsocket.handler import WebSocketHandler

class WebSocketApp(object):
def call(self, env, start_response):
ws = env[‘wsgi.websocket’]
x = 0
while True:
data = json.dumps({‘x’:x, ‘y’ :random.randint(1,5)})
ws.send(data)
x += 1
sleep(0.5)

server = pywsgi.WSGIServer((’’, 10000), WebSocketApp(), handler_class=WebSocketHandler)
server.serve_forever()

在html文件中点击浏览器

web1.png

就会一直打印数据

web2.png

群聊后端

# websocket
from geventwebsocket.server import WSGIServer # 我要WSGI为我提供服务
from geventwebsocket.handler import WebSocketHandler # WSGI 遇到 WS协议的时候,处理方式
from geventwebsocket.websocket import WebSocket # 语法提示

# 基于 Flask + geventwebsocket

from flask import Flask,request,render_template

app = Flask(__name__)

user_socket_list = []

@app.route("/ws")
def my_ws_func():
    # print(dir(request.environ))
    user_socket = request.environ.get("wsgi.websocket")  # type:WebSocket
    user_socket_list.append(user_socket)
    # web + socket
    print(user_socket)
    while 1:
        msg = user_socket.receive() # 等待接收客户端发送过来的消息
        for us in user_socket_list:
            if us == user_socket:
                continue
            try:
                us.send(msg)
            except:
                continue

        # print(msg)
        # user_socket.send(msg)

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

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

前端




    
    Title


    

发送消息:

单聊后端

要实现单聊,就必须实现消息格式数据结构能够拿到 发送者,接收者,信息,者三部分

简单示例

        """
        {
            to_user:YWB
            from_user:JWB
            message:"你就是一只WB"
        }
        """



# websocket
from geventwebsocket.server import WSGIServer # 我要WSGI为我提供服务
from geventwebsocket.handler import WebSocketHandler # WSGI 遇到 WS协议的时候,处理方式
from geventwebsocket.websocket import WebSocket # 语法提示

# 基于 Flask + geventwebsocket

from flask import Flask,request,render_template
import json

app = Flask(__name__)

# user_socket_dict = {"YWB":,
# "JWB":}

user_socket_dict = {}

@app.route("/ws/")
def my_ws_func(nickname):
    # print(dir(request.environ))
    user_socket = request.environ.get("wsgi.websocket")  # type:WebSocket
    user_socket_dict[nickname] = user_socket
    print(len(user_socket_dict),user_socket_dict)
    # web + socket
    print(user_socket)
    while 1:
        msg = user_socket.receive() # 等待接收客户端发送过来的消息
        print(msg)
        msg = json.loads(msg) # Dict
        """
        {
            to_user:YWB
            from_user:JWB
            message:"你就是一只WB"
        }
        """
        to_user_socket = user_socket_dict.get(msg.get("to_user"))
        msg_json = json.dumps(msg)
        to_user_socket.send(msg_json)

@app.route("/one_p")
def one_p():
    return render_template("one_p.html")
if __name__ == '__main__':
    # app.run()
    http_serv = WSGIServer(("0.0.0.0",9527),application=app,handler_class=WebSocketHandler)
    http_serv.serve_forever()

欢迎关注
在这里插入图片描述

单聊前端




    
    Title


    

登录

发送消息:

你可能感兴趣的:(flask)