1.settings.py

INSTALLED_APPS = [
'...',
'channels',
'...',
]
ASGI_APPLICATION = 'server.routing.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [(os.getenv('REDIS_SERVER_HOST', '127.0.0.1'), int(os.getenv('REDIS_SERVER_PORT', '')))],
},
},
}

2.routing.py(settin.py同级)

# -*- coding: utf-8 -*-

from channels.routing import ProtocolTypeRouter, URLRouter

from device.consumers import QueryAuthMiddleware  # websocket中间件
import device.routing # 路由 application = ProtocolTypeRouter({
'websocket': QueryAuthMiddleware(
URLRouter(
device.routing.websocket_urlpatterns
)
)
})
class QueryAuthMiddleware:
"""
WebSocket 认证中间件
"""
def __init__(self, inner):
# Store the ASGI application we were passed
self.inner = inner def __call__(self, scope):
query = parse.parse_qs(scope["query_string"].decode())
token = query.get('token', [None])[0]
device_name = None
try:
login_info = json.loads(base64.b64decode(token).decode())
device_name = login_info['name']
logger.info('Device {} connect from {} port {}'.format(device_name, scope['client'][0], scope['client'][1])) # 验证时间
gen_time = datetime.strptime(login_info['time'], '%Y%m%d%H%M%S')
now_time = datetime.now()
if abs(gen_time - now_time).total_seconds() > 5 * 60:
raise ValueError('Device {} time validate fail: token time: {}, server time: {}'.format(
device_name, gen_time.strftime('%Y-%m-%d %H:%M:%S'), now_time.strftime('%Y-%m-%d %H:%M:%S'))) # 验证密码
device = DeviceInfoModel.objects.get(name=device_name) # 获取到设备
correct = device.check_password(login_info['password']) # 检查密码
if not correct:
raise ValueError('Device {} password validate fail'.format(device_name)) except DeviceInfoModel.DoesNotExist:
logger.info('Device {} can not find in DB'.format(device_name))
device = None except Exception as e:
logger.error('Connect error {}'.format(e))
device = None finally:
# Middleware 中必须手动关闭数据库连接
# http://channels.readthedocs.io/en/latest/topics/authentication.html#custom-authentication
close_old_connections() return self.inner(dict(scope, user=device))

此时,启动方式也应该稍作调整(项目根目录下新建asgi.py文件)

"""
ASGI entrypoint. Configures Django and then runs the application
defined in the ASGI_APPLICATION setting.
""" import os
import django
from channels.routing import get_default_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
django.setup()
application = get_default_application()

客户端示例:

import threading
import time
import json
import tarfile
import base64
import hashlib
import os
import pickle
from io import BytesIO
from datetime import datetime import websocket def on_message(ws, message):
print('on_message')
msg = json.loads(message)
print(msg)
# print(msg['result'])
# print(pickle.loads(base64.b64decode(msg['content']['2-5b4747af5f627dbcb5eaefeb']))) def on_error(ws, error):
print(error) def on_close(ws):
print("### closed ###") def on_open(ws):
def run(*args):
# for i in range(1):
# tarobj = BytesIO()
# tar = tarfile.open(fileobj=tarobj, mode='w:gz')
# dir_list = filter(lambda name: os.path.isdir(name) and not name.startswith('.'), os.listdir(os.path.abspath(os.path.dirname('__file__'))))
# for dir in dir_list:
# tar.add(dir)
# tar.close()
# tarobj.seek(0)
with open('D:\\software\\websocket\websocket\\face\\18032811042400\\0.jpg', 'rb') as f:
base64_data = base64.b64encode(f.read())
s = base64_data.decode() file_obj = {
'timestamp': datetime.now().timestamp(),
'image': s
} info = {
'command': 'TEST',
'content': file_obj,
# 'content': ['30-5b691d365f627dee73c4b58d-common', '71-5b695edf5f627d762d5d651b'],
}
ws.send(json.dumps(info))
time.sleep(100)
ws.close()
print("thread terminating...")
threading.Thread(target=run).start() if __name__ == "__main__": websocket.enableTrace(True)
login_info = {
'name': '',
'password': hashlib.md5(''.encode('utf8')).hexdigest(),
'time': datetime.now().strftime('%Y%m%d%H%M%S')
} b64_token = base64.b64encode(json.dumps(login_info).encode()).decode()
url = "ws://xx.xx.xx.xx:8000/push/device/?token={}".format(b64_token)
print(login_info)
print('Connect {}'.format(url))
ws = websocket.WebSocketApp(url,
on_message=on_message,
on_error=on_error,
on_close=on_close)
ws.on_open = on_open
ws.run_forever()

参考:https://channels.readthedocs.io/en/latest/deploying.html

Django配置websocket请求接口的更多相关文章

  1. 使用ajax请求接口,跨域后cookie无法设置,全局配置ajax;及使用axios跨域后cookie无法设置,全局配置axios

    问题一: 使用ajax/axios跨域请求接口,后端放行了,能够正常获取数据,但是cookie设置不进去,后端登录session判断失效 ajax解决办法: //设置ajax属性 crossDomai ...

  2. 【uWSGI】实战之Django配置经验

    uWSGI 是应用服务器,实现了uwsgi, wsgi等协议,可以运行wsgi 应用 uwsgi 是协议名 Django配置 下面是自己经常用的一个配置模板,基于1.9以上的版本使用的, 主要基于dj ...

  3. Django实现websocket完成实时通讯,聊天室,在线客服等

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

  4. nginx配置websocket

    有时候我们需要给websocket服务端做一下nginx的配置,比如需要给websocket服务端做负载均衡,或者,有些系统要求访问websocket的时候不能带端口,这时候我们就需要用nginx来进 ...

  5. Django实现websocket完成实时通讯、聊天室、在线客服等

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

  6. django 实现websocket

    一.简述:django实现websocket,之前django-websocket退出到3.0之后,被废弃.官方推荐大家使用channels. channels通过升级http协议 升级到websoc ...

  7. 10 Django之Ajax请求

    一.什么是Ajax技术? 异步的JavaScript和XML.使用Javascript语言与服务器进行异步交互,传输的数据为XML(更多的使用json数据).Ajax不是一门新的编程语言,而是一种使用 ...

  8. Django实现websocket完成实时通讯

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

  9. Django实现websocket

    django实现websocket大致上有两种方式,一种channels,一种是dwebsocket.channels依赖于redis,twisted等 一 dwebsocket 1 Django实现 ...

随机推荐

  1. flutte的第一个hello world程序

    用命令行创建项目: flutter create flutterdemo VSCode或者AS连接手机后 输入 flutter run 编译后就可以将默认的代码显示在手机上了 开始写hello wor ...

  2. java-mybaits-014-数据库缓存设计【querycache、mybatis一级缓存、二级缓存】

    一.概述 一般来说,可以在5个方面进行缓存的设计: 1.最底层可以配置的是数据库自带的query cache, 2.mybatis的一级缓存,默认情况下都处于开启状态,只能使用自带的Perpetual ...

  3. Spring cloud微服务安全实战-5-5实现授权码认证流程(1)

    目前为止已经完成了完整的用户逻辑 目前的问题是,用户在登陆的时候,用户名提交的是给前端服务器的.每个前端服务器的开发人员都可能接触到前端的用户名密码. 每一个客户端应用都要去处理登陆的逻辑,一单我的登 ...

  4. win7、win10系统电脑开机后小键盘灯不亮怎么办?

    摘自:https://www.pconline.com.cn/win10/1113/11136072.html win7.win10系统 电脑开机后小键盘灯不亮怎么办?这是不少用户最近都在反馈的问题. ...

  5. 如何切换svn的登陆账号?

    如何切换svn的登陆账号? 听语音 原创 | 浏览:68661 | 更新:2017-10-06 09:09 1 2 3 4 5 6 分步阅读 对于程序员来说,svn使用的比较广泛,平时用来更新或者是提 ...

  6. HDU 2089 不要62 数位DP模板题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 参考博客:https://www.cnblogs.com/HDUjackyan/p/914215 ...

  7. 迅速生成项目-vue-cli-service

    推荐指数:

  8. LODOP指定window默认打印机和临时默认打印机

    通过以下语句,可指定windows默认打印机LODOP.SET_PRINT_MODE("WINDOW_DEFPRINTER",某打印机名或序号);这种默认打印机是指的windows ...

  9. CF1227D Optimal Subsequences

    思路: 首先对于单个查询(k, p)来说,答案一定是a数组中的前k大数.如果第k大的数字有多个怎么办?取索引最小的若干个.所以我们只需对a数组按照值降序,索引升序排序即可. 多个查询怎么办?离线处理. ...

  10. 高级UI-自定义动画框架

    有的时候会需要做一些自定义的动画效果,在会反复用到的动画效果可以考虑做成动画框架,方便使用,做成框架的话就需要考虑很多的问题,最典型的问题就是属性和方法必须要是可配置的,这里就来聊一聊自定义动画框架的 ...