Django - WebSocket:dwebsocket
Django - WebSocket:dwebsocket
什么是WebSocket
WebSocket是一种在单个TCP连接上进行全双工通信的协议
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。
在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
很可能用不到的判断
WebSocket 协议在2008年诞生,2011年成为国际标准,所有浏览器都已经支持了。你可以这么判断浏览器是否支持:
<script>
if ('WebSocket' in window) {
console.log('你的浏览器支持 WebSocket')
}
</script>
WebSocket for Django
django实现websocket大致上有两种方式,一种channels,一种是dwebsocket。channels依赖于redis,twisted等,相比之下使用dwebsocket要更为方便一些。
Install dwebsocket
pip install dwebsocket # 最新版
# 网上貌似说最新的不好用,我们可以下载大家使用较多的老版本
pip install dwebsocket==0.4.2
我开始就下的默认版本,然后报错:
AttributeError: 'WSGIRequest' object has no attribute 'is_websocket'
后来下载老版本就好了。
服务端常用方法或者属性
| 名称 | 描述 | 备注 |
|---|---|---|
| @accept_websocket | 处理websocket和HTTP请求 | 该装饰器用的较多 |
| @require_websocket | 仅处理websocket请求,拒绝HTTP请求 | |
| request.is_websocket() | 如果请求类型是websocket,返回True,否则返回False | 通常与@accept_websocket装饰器搭配 |
| request.websocket | 当websocket请求建立后,该请求具有一个websocket属性,可以通过该属性进行通信, | 如果request.is_websocket()是False,则这个属性为None。 |
| request.websocket.wait() | 阻塞接收消息 | |
| request.websocket.read() | 非阻塞接收消息 | |
| request.websocket.count_messages() | 返回队列中的消息数量 | |
| request.websocket.has_messages() | 如果有新消息返回True,否则返回False | |
| request.websocket.send() | 向客户端发送bytes类型的数据 | |
| request.websocket.close() | 服务器端主动关闭websocket服务 | |
| request.websocket.iter() | websocket迭代器 |
客户端的属性和方法
| 名称 | 类型 | 描述 |
|---|---|---|
| WebSocket | 对象 | 提供到服务端的双向通道 |
| onopen | 属性 | 当websocket连接时调用的事件处理程序 |
| onmessage | 属性 | 通知接收到消息的事件处理程序 |
| onerror | 属性 | 当出现错误时调用的事件处理程序 |
| onclose | 属性 | 当套接字关闭时调用的事件处理程序 |
| readState | 属性 | 报告websocket连接状态 |
| close | 方法 | 关闭websocket |
| send | 方法 | 使用websocket向服务端发送数据 |
| url | 属性 | 报告套接字的当前URL |
| protocol | 属性 | 报告服务器所选中的协议 |
| binaryType | 属性 | 由onmessage接收的二进制数据格式 |
| bufferedAmount | 属性 | 使用send的已排队的数据字节数 |
| extensions | 属性 | 包括服务器所选中的扩展名 |
关于readState,根据readState属性可以判断websocket的连接状态,该属性的值可以是以下几种:
| 属性值 | 对应常量 | 描述 | 备注 |
|---|---|---|---|
| 0 | CONNECTING | 正在建立连接 | 但还没有建立完毕 |
| 1 | OPEN | 连接成功建立,可以进行通信 | |
| 2 | CLOSING | 连接正在关闭 | 即将关闭 |
| 3 | CLOSED | 连接已关闭 | 或者根本没有建立连接 |
根据bufferedAmount可以知道有多少字节的数据等待发送,若websocket已经调用了close方法该属性将会一直增长。
必要的settings配置
# settings.py
MIDDLEWARE_CLASSES = [
'dwebsocket.middleware.WebSocketMiddleware'
]
WEBSOCKET_ACCEPT_ALL=True # 可以允许每一个单独的视图实用websocket
添加上这个中间件,就会拒绝单独的视图使用websocket,不过我们一般都是使用视图搭配websocket,所以,这个配置忘掉吧,顺便把第二个配置也忘掉,除非你要搞复杂的操作......
示例
环境
django1.11 + Python3.6 + PyCharm2018.1 + win10
Django中的配置
settings中保持默认即可
# urls.py
from django.conf.urls import url
from django.contrib import admin
from web import views # web是我的APP名称
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^test/', views.test, name='test'),
]
views.py:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
# from django.shortcuts import render
# Create your views here.
import json
import time
from django.shortcuts import render
from dwebsocket.decorators import accept_websocket
@accept_websocket
def test(request):
if request.is_websocket():
print "ws flag"
print('websocket connection....')
# msg = request.websocket.wait() # 接收前端发来的消息
# print help(request.websocket)
# msg = request.websocket
# print(msg, type(msg), json.loads(msg)) # b'["1","2","3"]' <class 'bytes'> ['1', '2', '3']
i = 0
while 1:
msg = request.websocket.wait() # 接收前端发来的消息
if msg:
# 你要返回的结果
# for i in range(10):
# request.websocket.send('service message: {}'.format(i).encode()) # 向客户端发送数据
request.websocket.send(raw_input("Please Enter Informaiton :").encode())
# time.sleep(0.5) # 每0.5秒发一次
i += 1
else:
request.websocket.close()
else: # 如果是普通的请求返回页面
print "http flag"
return render(request, 'test.html')
test.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>test</title>
</head>
<body>
<div></div>
</body>
<!-- 首先引入 jQuery -->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script>
// 判断浏览器是否支持WebSocket,目前应该所有的浏览器都支持了.....
if ('WebSocket' in window) {
console.log('你的浏览器支持 WebSocket')
}
// 创建一个WebSocket对象:sk,并且建立与服务端的连接(服务端程序要跑着哦)
var sk = new WebSocket('ws://' + window.location.host + '/test/');
// 向服务端发送消息
sk.onopen = function () {
console.log('websocket connection successful...');
var l = ['1', '2', '3'];
sk.send(JSON.stringify(l));
};
// 接收服务端的消息,主要的业务逻辑也在这里完成
sk.onmessage = function (msg) {
// 业务逻辑
html = "<p>" + msg.data + "</p>";
$("div").append(html);
console.log('from service message: ', msg.data);
// 由于服务端主动断开连接,这里也断开WebSocket连接
if (sk.readyState == WebSocket.CLOSED) sk.close();
};
// 完事就关闭WebSocket连接
sk.onclose = function (msg) {
console.log('websocket connection close...');
sk.close()
};
// 当WebSocket连接创建成功后,我们就可以向服务端发送数据了
if (sk.readyState == WebSocket.OPEN) sk.onopen();
</script>
</html>
测试
测试网站:
http://www.websocket-test.com/

原文:https://www.cnblogs.com/Neeo/articles/11551731.html
Django - WebSocket:dwebsocket的更多相关文章
- Nginx+uWSIG+Django+websocket的实现
1.Django+websocket django-websocket dwebsocket django-websocket是旧版的,现在已经没有人维护,dwebsocket是新版的,推荐使用dwe ...
- Django教程:第一个Django应用程序(4)
Django教程:第一个Django应用程序(4) 2013-10-09 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 #博客: ...
- Django教程:第一个Django应用程序(3)
Django教程:第一个Django应用程序(3) 2013-10-08 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 #博客: ...
- Python开发【Django】:基础
Django基本配置 Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Se ...
- Django RF:学习笔记(8)——快速开始
Django RF:学习笔记(8)——快速开始 安装配置 1.使用Pip安装Django REST Framework: pip install djangorestframework 2.在Sett ...
- django迁移:全局、局部
django迁移:全局.局部 django 数据库迁移(migrate)应该知道的一些事 https://blog.csdn.net/stonesola/article/details/6975861 ...
- WebSocket :Nginx+WebSocket内部路由策略推送服务器的实现(附可生产环境应用代码)
1.项目背景 前几天写了一篇WebSocket推送的博客:WebSocket :用WebSocket实现推送你必须考虑的几个问题 支持的连接数大概几千个,具体数量依赖于tomcat能并发的线程数,但很 ...
- Django笔记:常见故障排除
Django框架下MySQLdb模块在python3中无法使用的问题的解决方案 由于python3环境下目前还没有官方的mysqldb模块,Django框架中又强制要求使用mysqldb,为了解决这个 ...
- 05 django组件:contenttype
1.django组件:contenttype 组件的作用:可以通过两个字段让表和N张表创建FK关系 1.专题课,学位课 如何关联 过期时间?? 方法1:分别创建 专题课--过期时间表 .学位课--过期 ...
随机推荐
- 栈的应用:表达式括号匹配检测(C)
问题说明: 假设数学表达式中允许包含两种括号:圆括号"()"和方括号"[]",嵌套顺序任意. 正确的嵌套模式:( [ ] ( ) ).[ ( [ ] [ ] ) ...
- 浅入 AutoMapper
目录 浅入 AutoMapper AutoMapper 基本使用 映射配置 映射检查 性能 Profile 配置 依赖注入 表达式与 DTO 浅入 AutoMapper 在 Nuget 搜索即可安装, ...
- 多任务-python实现-使用队列完成进程间的通信(2.1.8)
@ 目录 1.为什么要使用队列 2.python代码实现 1.为什么要使用队列 进程之间是互相独立的,而线程能够共享全局变量 所以如果进程间想要交换数据的话 只有通过进程间的通信,比如socket.太 ...
- Redis史上最全文章教程
Redis 2020 史上最详细Redis教程 本篇文章并不讲解Redis,只是收集 Redis的优质文章教程 ,文章包含三部分: 理论.编程实战 .面试题. 需要有一定编程功底的人学习 ,如果基础不 ...
- 利用基于Go Lang的Hugo配合nginx来打造属于自己的纯静态博客系统
Go lang无疑是目前的当红炸子鸡,极大地提高了后端编程的效率,同时有着极高的性能.借助Go语言我们 可以用同步的方式写出高并发的服务端软件,同时,Go语言也是云原生第一语言,Docker,Kube ...
- Typora+Picgo+Gitee实现上传图片
下载picgo和node.js 百度网盘地址: 链接:https://pan.baidu.com/s/1QwbXn4vFuDfSFNOnZU5-Jg 取码:efgc 打开picgo,安装gitee-u ...
- robots.txt协议如何设置禁止搜索引擎抓取?
什么情况下要设置禁止搜索引擎抓取自己的网站呢? 公司内部测试的网站,或者内部网,或者后台登录的页面,肯定不希望被外面的人搜索到,所以要禁止搜索引擎抓取.还有在我们的网站还未正式上线之前,我们需要做大量 ...
- npm 各种常用命令
全局删除 node-gyp npm -g uninstall node-gyp 再次安装依赖 npm install 更改包内容后重建 npm rebuild 清除缓存 npm cache clean ...
- java中定时器设置时间
<!-- 0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 0 0 12 ? * WED 表示每个星期三中午1 ...
- SpringBoot 获取微信小程序openid
最近做一个项目用到小程序,为了简化用户啊登录,通过获取小程序用户的openid来唯一标示用户. 1.官方教程 2.具体步骤 3.具体实现 4.可能出现的错误 5.代码下载 1.官方教程 先来看看官方怎 ...