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. FFmpeg 初级使用

    ffmpeg来处理多种媒体文件,对帧进行操作的时候非常的复杂,下面介绍下使用FFmpeg对视频文件的操作. 1,安装 windows安装ffmpeg: 下载ffmpeg文件解压文件到c盘配置环境变量C ...

  2. 对着爬虫网页HTML学习Python正则表达式re

    1.正则表达式初探 用比较经典的例子,查找一段文本中的手机号码.比如对于文本"我现在用的电话是188-8888-8888,之前那个186-6666-6666已经不用了",我们想获取 ...

  3. C#中string类型必填的诡异问题

    背景 ASP.NETCore3.0项目,使用Swagger接口文档. 之前的项目都是Swashbuckle.AspNetCore-5.0.0 新项目想尝尝鲜,用最新版Swashbuckle.AspNe ...

  4. [UWP] - 修改应用程序在任务栏上的显示Logo

    用VS2015在windows 10上开发一个UWP的应用,由于windows 10对store应用进行了窗口化,因此可以看到在任务栏上看到应用程序的图标,但是看起来会感觉应用Logo会被嵌在另一个容 ...

  5. Centos7安装packstack

    Centos7安装packstack 步骤一 下载centos7.6 https://archive.kernel.org/centos-vault/7.6.1810/isos/x86_64/Cent ...

  6. umi-request 统一异常处理实践

    首发于语雀文档 前言 本人在工作中用到了 umi-request,百度谷歌搜了一遍,感觉都没找到超过 3 篇合适且含代码的文章,因此只能自行实践总结了. umi-request 有点不同 umi-re ...

  7. ajax上传单个文件

    jsp页面 <%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML> ...

  8. flowable 任务多实例

    项目地址:https://gitee.com/lwj/flowable.git 分支flowable-base*业务场景:收集每个员工的绩效考核信息:收集一次组织活动的信息:一个合同需要三个经理审批, ...

  9. 白嫖JetBrains正版全家桶!

    使用自己的开源项目,是可以白嫖JetBrains正版全家桶的! 前言 之前在学Go的时候,想着要用什么编辑器,网上的大佬都讲,想省事直接用Goland,用VsCode配置会存在一些未知的使用体验问题, ...

  10. Linux嵌入式学习-交叉编译openssl

    利用arm-none-linux-gnueabi-gcc交叉编译openssl,生成静态库文件libcrypto.a ,libssl.a 1.从openssl官网下载openssl最新版本,我下载的是 ...