WebSocket长连接
WebSocket长连接
1、概述


1.1 定义

1.2 原理

2、Django中配置WebSocket
2.1安装第三方法包
-
pip install channels
2.2 Django 中的配置
-
Settings中的配置
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'channels',#注册APP ] -
添加配置
- 定位到Django3中的asgi.py下的application
ASGI_APPLICATION = "djangoWS.asgi.application"- 修改asgy.py文件
- 默认只支持http协议,修改其内容使得即支持HTTP又要支持WebSocket;
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', 'djangoWS.settings') # 默认只支持http请求 # application = get_asgi_application() application=ProtocolTypeRouter({ "http":get_asgi_application(), "websocket":URLRouter(routing.websocket_urlpatterns), }) -
在Settings.py的同级目录下,创建routing.py;
# -*- coding: utf-8 -*- ''' @Time : 2021/11/12 9:00 @Author : ziqingbaojian @File : routing.py ''' from django.urls import re_path from app01 import consumers websocket_urlpatterns=[ re_path(r'ws/?P\w+/$',consumers.ShowNum.as_asgi()) ] -
在app01下创建consumers.py,编写处理事务的逻辑。
# -*- coding: utf-8 -*- ''' @Time : 2021/11/12 9:11 @Author : ziqingbaojian @File : consumers.py ''' from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer # 继承WebsocketConsumer class ShowNum(WebsocketConsumer): def websocket_connect(self, message): # 有客户端来向后端发送WebSocket连接请求时,自动触发 # 允许客户端的连接 self.accept() # raise StopConsumer()# 不创建连接,直接使用raise将异常抛出; def websocket_receive(self, message): # 基于WebSocket想后端发送数据,自动触发接收数据 # 接收到前端传回的消息 self.send("不要回答,不要回答,不要回答") def websocket_disconnect(self, message): # 客户端与服务端断开连接时,自动触发 raise StopConsumer()
2.3 django中需要了解的
-
wsgi:django3以前django属于同步的,wsgi是处理Socket
-
asgi : 相当于wsgi+异步+WebSocket
-
普通启动,默认使用的是wsgi**

-
基于asgi/channels启动

3、聊天室
-
访问到地址界面,http请求
-
让客户端向服务端主动发送websocket连接,服务端收到连接后(握手)。
-
前端
//websocket的协议,发送数据要带ws相当于,http请求以http开头一样; socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")-
服务端
from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer # 继承WebsocketConsumer class ShowNum(WebsocketConsumer): def websocket_connect(self, message): # 有客户端来向后端发送WebSocket连接请求时,自动触发 # 允许客户端的连接(握手) print("连接来拉") self.accept() '''两次请求,连接一次握手一次''' # raise StopConsumer()# 不创建连接,直接使用raise将异常抛出; -
3.1 收发消息( 客户端-->服务端)
-
客户端
Title -
服务端
# -*- coding: utf-8 -*- ''' @Time : 2021/11/12 9:11 @Author : ziqingbaojian @File : consumers.py ''' from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer # 继承WebsocketConsumer class ShowNum(WebsocketConsumer): def websocket_receive(self, message): # 基于WebSocket想后端发送数据,自动触发接收数据 # 接收到前端传回的消息 print(message) self.send("不要回答,不要回答,不要回答")
3.2 收发消息(服务端-->客户端)
-
服务端
from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer # 继承WebsocketConsumer class ShowNum(WebsocketConsumer): def websocket_connect(self, message): # 有客户端来向后端发送WebSocket连接请求时,自动触发 # 允许客户端的连接(握手) print("连接来拉") self.accept() '''两次请求,连接一次握手一次''' # raise StopConsumer()# 不创建连接,直接使用raise将异常抛出; # 服务端给客户端发送消息 self.send("来了呀,哈哈哈") -
客户端
3.2 前端补充回调函数
3.3 关闭连接
-
客户端主动关闭
- 客户端
Title - 服务端
# -*- coding: utf-8 -*- from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer # 继承WebsocketConsumer class ShowNum(WebsocketConsumer): def websocket_disconnect(self, message): # 客户端与服务端断开连接时,自动触发 print("断开连接了") raise StopConsumer() -
服务端主动关闭连接
- 服务端
from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer # 继承WebsocketConsumer class ShowNum(WebsocketConsumer): def websocket_receive(self, message): # 基于WebSocket想后端发送数据,自动触发接收数据 # 接收到前端传回的消息 print(message) text=message['text'] print(text) self.send("不要回答,不要回答,不要回答") if text=="close": # 法一 self.close()# 会触发前端的onCllose方法; return # 不在执行后期的代码 # 法二 # raise StopConsumer()# 如果服务端断开连接时,执行了StopConsumer异常,那么websocket_disconnect方法不在执行;- 客户端
3.4 整合代码示例
-
服务端
from channels.generic.websocket import WebsocketConsumer from channels.exceptions import StopConsumer # 继承WebsocketConsumer class ShowNum(WebsocketConsumer): def websocket_connect(self, message): # 有客户端来向后端发送WebSocket连接请求时,自动触发 # 允许客户端的连接(握手) print("连接来拉") self.accept() '''两次请求,连接一次握手一次''' # raise StopConsumer()# 不创建连接,直接使用raise将异常抛出; # 服务端给客户端发送消息 self.send("来了呀,哈哈哈") def websocket_receive(self, message): # 基于WebSocket想后端发送数据,自动触发接收数据 # 接收到前端传回的消息 print(message) text=message['text'] print(text) self.send("不要回答,不要回答,不要回答") if text=="close": # 法一 self.close()# 会触发前端的onCllose方法; return # 不在执行后期的代码 # 法二 # raise StopConsumer()# 如果服务端断开连接时,执行了StopConsumer异常,那么websocket_disconnect方法不在执行; def websocket_disconnect(self, message): # 客户端与服务端断开连接时,自动触发,包括关闭页面与浏览器的情况 print("断开连接了") raise StopConsumer() -
客户端
Title
3.5 群聊功能
- 配置django中的配置文件或者,自定义设置连接池
4 、vue中使用Webscoket
-
参考文献1:
-
参考文献2 :
-
方法一
-
方法二