美文网首页
django 之dewebsocket

django 之dewebsocket

作者: 朱佩奇被占用 | 来源:发表于2020-06-29 16:05 被阅读0次

最近又被要求用dewebsocket 来做两台机器的实时沟通(这边是两个大屏做实时响应),这边最土的方法就是用轮询,然而 最好的的方法就是用websocket来建立长连接

什么是webscoket

WebSocket是一种在单个TCP连接上进行全双工通信的协议

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯

如何去实现websocket

可以用channels 我这边使用的是dewebsocket(纯属为了简单方便)

dewebsocket安装

pip install dwebsocket

setting.py 配置

import dwebsocket # 放在SECRET_KEY下方
INSTALLED_APPS = [
    .....
    .....
    'dwebsocket',
]
 
MIDDLEWARE_CLASSES = [
    'dwebsocket.middleware.WebSocketMiddleware'  # 为所有的URL提供websocket,如果只是单独的视图需要可以不选
]
WEBSOCKET_ACCEPT_ALL=True   # 可以允许每一个单独的视图实用websockets

Vue

websoc(value) {
            // console.log(value)
            // const { data: res } = await this.$axios.post('/population/screen_two')
            // if(res.code !== 200) {
            //     return this.$message.error('请求失败,请检查服务器状态')
            // }
            // this.$message.success('请求成功')

            var ws = new WebSocket('ws://127.0.0.1:8000/population/screen_two/');
            //申请一个WebSocket对象,参数是服务端地址,同http协议使用http://开头一样,WebSocket协议的url使用ws://开头,另外安全的WebSocket协议使用wss://开头
            ws.onopen = function() {
                //当WebSocket创建成功时,触发onopen事件
                console.log('open');
                ws.send(value); //将消息发送到服务端
            };
            ws.onmessage = function(e) {
                //当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据
                console.log(e.data);
            };
            ws.onclose = function(e) {
                //当客户端收到服务端发送的关闭连接请求时,触发onclose事件
                console.log('close');
                ws.close();
            };
            ws.onerror = function(e) {
                //如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
                console.log(error);
            };
        }

django .views

clients = {}
client_names_dict = dict()
USER_MSG = 0


@accept_websocket
def screen_two(request):
    if request.is_websocket():
        print("server: enter the websocket")
        if request.is_websocket():
            userid = str(uuid.uuid1())[:8]
            clients[userid] = request.websocket

            while True:
                message = request.websocket.wait()  # block
                if not message:
                    break
                else:
                    msg = str(message, encoding="utf-8")
                    print(msg)
                    msg, user_name = msg.split("_")
                    # if msg == "test":
                    print("client ok:" + userid)
                    client_names_dict[userid] = user_name
                    # request.websocket.send(json.dumps(
                    #     {"type": USER_MSG, "user_list": list(client_names_dict.values()), "user_id": userid,
                    #      "user_name": user_name}).encode("'utf-8'"))
                    request.websocket.send(msg)
                    for client in clients:
                        # clients[client].send(json.dumps(
                        #     {"type": USER_MSG, "user_list": list(client_names_dict.values()), "user": None}).encode(
                        #     "'utf-8'"))
                        clients[client].send(msg)
        if userid in clients:
            del clients[userid]
            del client_names_dict[userid]
            print(userid + "offline")
            for client in clients:
                clients[client].send(
                    json.dumps({"type": USER_MSG, "user_list": list(client_names_dict.values()), "user": None}).encode(
                        "'utf-8'"))

这个可以做群发 一个生产者 多一个消费者

详解

dwebsocket有两种装饰器:require_websocket和accept_websocekt,使用require_websocket装饰器会导致视图函数无法接收导致正常的http请求,一般情况使用accept_websocket方式就可以了,

dwebsocket的一些内置方法:

request.is_websocket():判断请求是否是websocket方式,是返回true,否则返回false
request.websocket: 当请求为websocket的时候,会在request中增加一个websocket属性,
WebSocket.wait() 返回客户端发送的一条消息,没有收到消息则会导致阻塞
WebSocket.read() 和wait一样可以接受返回的消息,只是这种是非阻塞的,没有消息返回None
WebSocket.count_messages()返回消息的数量
WebSocket.has_messages()返回是否有新的消息过来
WebSocket.send(message)像客户端发送消息,message为byte类型

原文链接:https://www.cnblogs.com/liuqingzheng/p/10151572.html#_labelTop

相关文章

网友评论

      本文标题:django 之dewebsocket

      本文链接:https://www.haomeiwen.com/subject/ozoofktx.html