Django+Vue实现WebSocket连接的示例代码

2020-06-13 10:17:45易采站长站整理

近期有一需求:前端页面点击执行任务,实时显示后端执行情况,思考一波;发现

WebSocket
最适合做这件事。

效果

测试

ping www.baidu.com
效果

点击连接建立ws连接

后端实现

所需软件包

后端主要借助Django

Channels
实现socket连接,官网文档链接

这里想实现每个连接进来加入组进行广播,所以还需要引入

channels-redis

pip


channels==2.2.0
channels-redis==2.4.0

引入

settings.py


INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework.authtoken',
'rest_framework',
...
'channels',
]

# Redis配置
REDIS_HOST = ENV_DICT.get('REDIS_HOST', '127.0.0.1')
REDIS_PORT = ENV_DICT.get('REDIS_PORT', 6379)
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [(REDIS_HOST, REDIS_PORT)],
},
},
}

代码

apps/consumers.py

新建一个消费处理

实现: 默认连接加入组,发送信息时的处理。


from channels.generic.websocket import WebsocketConsumer

class MyConsumer(WebsocketConsumer):
def connect(self):
"""
每个任务作为一个频道
默认进入对应任务执行频道
"""
self.job_name = self.scope['url_route']['kwargs']['job_name'] self.job_group_name = 'job_%s' % self.job_name
async_to_sync(self.channel_layer.group_add)(
self.job_group_name,
self.channel_name
)
self.accept()

def disconnect(self, close_code):
async_to_sync(self.channel_layer.group_discard)(
self.job_group_name,
self.channel_name
)

# job.message类型处理
def job_message(self, event):

# 默认发送收到信息
self.send(text_data=event["text"])

apps/routing.py

ws类型路由

实现:ws/job/<job_name>由

MyConsumer
去处理。


from . import consumers
from django.urls import path
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.sessions import SessionMiddlewareStack

application = ProtocolTypeRouter({