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:分别创建 专题课--过期时间表 .学位课--过期 ...
随机推荐
- Linux简单复习
cd 命令:切换目录 ls命令:用于浏览目录下的文件或者文件夹 rm 命令:用于删除文件或者目录,用法 rm –rf test.txt (-r表示递归,-f表示强制) cp 命令:用于拷贝文件,用法, ...
- 这嘎哒真TM那啥!Python版东北话编程火爆网络
还记得那个刷爆朋友圈的那个文言文编程语言么? 这个项目是一位名为Huang Lingdong的大四学生创建的,当时,就连中科院计算所研究员.机器翻译领域知名专家刘群老师都赞叹道: 后生可畏 近日,Gi ...
- EF Core 封装方法Expression<Func<TObject, bool>>与Func<TObject, bool>区别
unc<TObject, bool>是委托(delegate) Expression<Func<TObject, bool>>是表达式 Expression编译后就 ...
- 什么是泛型?,Set集合,TreeSet集合自然排序和比较器排序,数据结构-二叉树,数据结构-平衡二叉树
==知识点== 1.泛型 2.Set集合 3.TreeSet 4.数据结构-二叉树 5.数据结构-平衡二叉树 ==用到的单词== 1.element[ˈelɪmənt] 要素 元素(软) 2.key[ ...
- git文件锁定不更新和忽略
git文件的忽略 新建未提交的文件直接添加.gitignore 提交之后的文件已被git追踪 这时需要清除git缓存 忽略文件 git rm --cached ./src/main/resources ...
- 有了它(powermock)再也不担心单元测试不达标了
为什么要写单元测试 优点:单元测试可以减少bug率,提升代码的质量.还可以通过单元测试来熟悉业务. 公司硬性要求:有些公司可能还会强制要求,每次新增代码.或者变更代码单测覆盖率要达到多少比例才能申请代 ...
- pyspark使用-dataframe操作
一.读取csv文件 1.用pandas读取 import pandas as pd from pyspark.sql import SparkSession spark=SparkSession.bu ...
- 注意力论文解读(1) | Non-local Neural Network | CVPR2018 | 已复现
文章转自微信公众号:[机器学习炼丹术] 参考目录: 目录 0 概述 1 主要内容 1.1 Non local的优势 1.2 pytorch复现 1.3 代码解读 1.4 论文解读 2 总结 论文名称: ...
- Elasticsearch java api操作(二)(Java High Level Rest Client)
一.说明: 一.Elasticsearch提供了两个JAVA REST Client版本: 1.java low level rest client: 低级别的rest客户端,通过http与集群交互, ...
- spark的thriftservr的高可用
triftserver是基于jdbc的一个spark的服务,可以做web查询,多客户端访问,但是thriftserver没有高可用,服务挂掉后就无法在访问,所有使用注册到zk的方式来实现高可用 一.版 ...