ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Django WebSocket笔记

2022-01-23 14:02:43  阅读:191  来源: 互联网

标签:websocket asgi self await 笔记 Django WebSocket import data


1.原理

webSocket协议,是建立在http协议之上的

  • 客户端发起连接,生成一个随机字符串后发给服务器
GET /chatsocket HTTP/1.1
Host: 127.0.0.1:8002
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:63342
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: mnwFxiOlctXFN/DeMt1Amg==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
...
...
  • 服务器接收,与magic_string拼接,后处理
magic_string = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

v1 = "mnwFxiOlctXFN/DeMt1Amg==" + magic_string
v2 = hmac1(v1)
v3 = base64(v2)
  • 服务器返回数据
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Pragma: no-cache
Sec-WebSocket-Accept: 上面的密文
  • 收发数据,会进行加密

  • 断开连接

2.Django Clannels实现

在Django中,wsgi:默认支持;asgi:支持http+websocket

同步请求:客户端向服务器发送请求-->等待服务器响应-->处理完毕返回,客户端浏览器没有做别的事情。

异步请求:通过事件触发请求-->服务器处理请求-->处理完毕返回,但是客户端浏览器可以接着做别的事情

  • 安装模块
pip install channels
  • 配置
#setting.py
INSTALLED_APPS = [
    ...
    'channels',
]

# 指定ASGI的路由地址
ASGI_APPLICATION = 'XiangDataDisplaySys.asgi.application'
  • setting同级目录下创建/修改asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter

from . import routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'XiangDataDisplaySys.settings')#参数2:工程名.settings

application = ProtocalTypeRouter({
    "http": get_asgi_application(),							#自动找urls.py
    "websocket": URLRouter(routing.websocket_urlpatterns),	#创建routings,创建comsumers
})
  • 在setting同级目录下创建routings.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.conf.urls import url
from django.core.asgi import get_asgi_application
from XiangDataDisplaySys import routings

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "XiangDataDisplaySys.settings")

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            routings.websocket_urlpatterns
        )
    ),
})
  • 在app目录下创建routings.py
from django.conf.urls import re_path
from appDataDisplay import consumers

websocket_urlpatterns = [
    re_path(r'^chat-channel/',consumers.ChatConsumer.as_asgi())
]
  • 在app目录下创建consumers.py
#异步处理代码
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.exceptions import StopConsumer

CONN_LIST = []

class ChatConsumer(AsyncWebsocketConsumer):
    #groups = ["broadcast"]

    async def connect(self):
        # Called on connection.
        # To accept the connection call:
        await self.accept()
        # Or accept the connection and specify a chosen subprotocol.
        # A list of subprotocols specified by the connecting client
        # will be available in self.scope['subprotocols']
        #await self.accept("subprotocol")
        # To reject the connection, call:
        #await self.close()
        print("来了来了.....")
        CONN_LIST.append(self)
        #await self.send(text_data="要回复要回复!!!")

    async def receive(self, text_data=None, bytes_data=None):
        # Called with either text_data or bytes_data for each frame
        # You can call:
        print(text_data)
        await self.send(text_data="不要回复不要回复!!!")
        # # Or, to send a binary frame:
        # await self.send(bytes_data="Hello world!")
        # # Want to force-close the connection? Call:
        # await self.close()
        # # Or add a custom WebSocket error code!
        # await self.close(code=4123)

    async def disconnect(self, close_code):
        # Called when the socket closes
        print("失去了连接.....")
        raise StopConsumer()
        CONN_LIST.remove(self)
  • 前端javascript代码
 //链接服务器
let websocket = new WebSocket('ws://127.0.0.1:8000/msg/');
//指定事件回调
websocket.onmessage =  function(e){ 
    //var data = JSON.parse(e.data);
    //console.log(data);
    console.log(e);
}
websocket.onopen = function(e){
    console.log(e);
}
websocket.onerror = function(e){
    console.log(e);
}
websocket.onclose = function(e){
    console.log(e);
}

var interval = setInterval(function() { 
    websocket.send("你好好!!!");
}, 1000);  //5秒循环调用执行remind()函数

标签:websocket,asgi,self,await,笔记,Django,WebSocket,import,data
来源: https://www.cnblogs.com/09w09/p/15836234.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有