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的更多相关文章

  1. Nginx+uWSIG+Django+websocket的实现

    1.Django+websocket django-websocket dwebsocket django-websocket是旧版的,现在已经没有人维护,dwebsocket是新版的,推荐使用dwe ...

  2. Django教程:第一个Django应用程序(4)

    Django教程:第一个Django应用程序(4) 2013-10-09 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 #博客: ...

  3. Django教程:第一个Django应用程序(3)

    Django教程:第一个Django应用程序(3) 2013-10-08 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 #博客: ...

  4. Python开发【Django】:基础

    Django基本配置 Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Se ...

  5. Django RF:学习笔记(8)——快速开始

    Django RF:学习笔记(8)——快速开始 安装配置 1.使用Pip安装Django REST Framework: pip install djangorestframework 2.在Sett ...

  6. django迁移:全局、局部

    django迁移:全局.局部 django 数据库迁移(migrate)应该知道的一些事 https://blog.csdn.net/stonesola/article/details/6975861 ...

  7. WebSocket :Nginx+WebSocket内部路由策略推送服务器的实现(附可生产环境应用代码)

    1.项目背景 前几天写了一篇WebSocket推送的博客:WebSocket :用WebSocket实现推送你必须考虑的几个问题 支持的连接数大概几千个,具体数量依赖于tomcat能并发的线程数,但很 ...

  8. Django笔记:常见故障排除

    Django框架下MySQLdb模块在python3中无法使用的问题的解决方案 由于python3环境下目前还没有官方的mysqldb模块,Django框架中又强制要求使用mysqldb,为了解决这个 ...

  9. 05 django组件:contenttype

    1.django组件:contenttype 组件的作用:可以通过两个字段让表和N张表创建FK关系 1.专题课,学位课 如何关联 过期时间?? 方法1:分别创建 专题课--过期时间表 .学位课--过期 ...

随机推荐

  1. Python高级语法-多继承MRO相关-args和kwargs(4.5.2)

    @ 目录 1.说明 2.代码 关于作者 1.说明 args数据类型为元组 kwargs数据类型为字典 一般传入方法中使用遍历去得到值 这个传入参数的顺序没有特殊的要求 当你自定义的参数传完以后,写了名 ...

  2. disable_functions Bypass

    参考文章和poc(文中均有poc下载地址) : https://www.uedbox.com/post/59295/ https://www.uedbox.com/post/59402/ 当然 fre ...

  3. python2与python3共存后,如何使用

    借用py的一个参数 py -2 与py -3调用不同是的python版本 所以运行的时候只要 py -2 文件名可以用python2来运行脚本 py -3 文件名就是用python3 来运行脚本 参考 ...

  4. C# 汉字转拼音 取汉字拼音的首字母

    using System.Text.RegularExpressions; namespace DotNet.Utilities { /// <summary> /// 汉字转拼音类 // ...

  5. 2021年第一个flag

    2021年开始更新本文列出的系列文章,根据书籍和自己的理解整理出spring框架的相关的学习 Spring 的设计理念和整体架构 学习目标 Spring的各个子项目 Spring的设计目标 Sprin ...

  6. 认识 YUV

    什么是 YUV YUV是一种颜色编码格式,可以说YUV流媒体是原始流数据,大部分的视频领域都在使用.与RGB类似,但RGB更多的用于渲染时,而YUV则用在数据传输,因为它占用更少的频宽.当然,实时通讯 ...

  7. Qt学习笔记-制作一个文本编辑器

    创建一个MainWindow工程.添加一个TextEdit.垂直布局. 在menu上面创建新的action. 在新建的时候判断文本有没有被修改. 下面,将某个文件打开读入到TextEdit中. 保存文 ...

  8. JDK下载地址 Oracle JDK下载 地址 (已解决)

    现在JDK开始收费了 Oracle官方对JDK的管理也变得严格了,现在想要在官网下载jdk需要先注册Oracle账号,这倒是小事但是网页反应慢注册填写内容复杂导致很多人不想注册. 不过有的人提供了公开 ...

  9. java键盘输入方法-

    字符串缓冲方式 BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); String line = null ...

  10. select机制

    select机制 函数作用: 在一段时间指定的时间内,监听用户感兴趣的文件描述符上可读.可写和异常事件. 函数原型: #include <sys/time.h> #include < ...