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. 安利一个基于Spring Cloud 的面试刷题系统。面试、毕设、项目经验一网打尽

    推荐: 接近100K star 的Java学习/面试指南 Github 95k+点赞的Java面试/学习手册.pdf 今天给小伙伴们推荐一个朋友开源的面试刷题系统. 这篇文章我会从系统架构设计层面详解 ...

  2. Abp(net core)+easyui+efcore实现仓储管理系统——出库管理之八(五十七)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ...

  3. [LeetCode]144. Binary Tree Preorder Traversal二叉树前序遍历

    关于二叉树的遍历请看: http://www.cnblogs.com/stAr-1/p/7058262.html /* 考察基本功的一道题,迭代实现二叉树前序遍历 */ public List< ...

  4. 【探索之路】机器人篇(3)-给mwRobot建立模型

    在创建一个mwRobot_description程序包那一节中,我们添加了依赖roscpp  rospy std_msgs 和 urdf , 现在我们再添加一个xacro依赖. 如何添加依赖? 打开程 ...

  5. 相对于Statement,PreparedStatement的优点是什么?

    优点: 1.PreparedStatement有助于防止SQL注入,因为它会自动对特殊字符转义. 2.PreparedStatement可以用来进行动态查询. 3.PreparedStatement执 ...

  6. Python & Matplotlib: Monte Carlos Method

    Hey! 这里是Lindy:) Hope you guys are doing well! 今天想记录的概念叫做 蒙特·卡罗 方法,是今年在cs课上老师做的扩展延伸.其实我在初次接触这个概念时觉得很新 ...

  7. .NET 云原生架构师训练营(模块二 基础巩固 MongoDB 介绍和基础)--学习笔记

    2.5.1 MongoDB -- 介绍 mysql vs mongo 快速开始 mysql vs mongo 对比 mysql mongo 数据存储 table 二维表结构,需要预先定义结构 json ...

  8. 异步技巧之CompletableFuture

    摘自--https://juejin.im/post/5b4622df5188251ac9766f47 异步技巧之CompletableFuture 1.Future接口 1.1 什么是Future? ...

  9. DBF 文件 ORACLE 数据库恢复

    DBF 文件 ORACLE 数据库恢复 清·魏源<庸易通义>:"至道问学之有知无行,分温故为存心,知新为致知,而敦厚为存心,崇礼为致知,此皆百密一疏." 起因 在我们的 ...

  10. linux系统修改不成功无法修改密码

    一.问题描述 新上架的浪潮服务器使用装机平台进行统一安装,安装完成后修改用户密码时统一无法修改,使用root账户无法修改其他用户密码,自身根密码也无法修改成功,报错如下 Changing passwo ...