一、简述:django实现websocket,之前django-websocket退出到3.0之后,被废弃。官方推荐大家使用channels。

channels通过升级http协议 升级到websocket协议。保证实时通讯。也就是说,我们完全可以用channels实现我们的即时通讯。而不是使用长轮询和计时器方式来保证伪实时通讯。

他通过改造django框架,使django既支持http协议又支持websocket协议。

官方文档地址:https://channels.readthedocs.io/en/stable/

二:安装

python version:2.7 3.4 3.5

安装channels:

 pip install -U channels

在安装在windows机器的时候。需要自信的C++支持,报错的时候,报错有地址告诉你下载URL。

配置:

需要在seting.py里配置,将我们的channels加入INSTALLED_APP里。

 INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
...
'channels',
)

这样django就支持websocket了,接下来我们需要配置一些简单的配置。

三:概念阐述:

channels: It is an orderedfirst-in first-out queue with message expiry and at-most-once delivery to only one listener at a time.

它是先进先出的消息队列,同一时刻只向一个消费者发送一个没有过期的消息。这里的消费者类似订阅者,或者客户端。

默认的channels是http.request.在这种情况下运行 django 和之前的没使用websocket来说没有什么特别。

通过查看源码我们可以看到其他的channels:

至于我们是否可以自定义channels目前没有验证!

介绍下channels结构:

首先需要建立一个django项目。其中在你自己的app下面 生成consumers.py和routing.py配置文件。

consumers.py:相当于django的视图,也就是说所有的websocket路由过来的执行的函数都在consumers.py类似于django的视图views.py

routing.py:是websocket中的url和执行函数的对应关系。相当于django的urls.py,根据映射关系,当websocket的请求进来的时候,根据用户的请求来触发我们的consumers.py里的方法。

四:代码示例

consumer.py

 
 # In consumers.py

 def ws_message(message):
# ASGI WebSocket packet-received and send-packet message types
# both have a "text" key for their textual data.
message.reply_channel.send({
"text": message.content['text'],
})

routing.py

 # In routing.py
from channels.routing import route
from myapp.consumers import ws_message channel_routing = [
route("websocket.receive", ws_message),
]

websocket.receive表示当用户请求的时候,自动触发后面的ws_message.

html  code:html5支持websocket。

 <!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>测试websocket</title> <script type="text/javascript">
function WebSocketTest()
{
if ("WebSocket" in window)
{
alert("您的浏览器支持 WebSocket!"); // 打开一个 web socket
ws = new WebSocket("ws://localhost:8000/path/"); ws.onopen = function()
{
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("发送数据");
alert("数据发送中...");
}; ws.onmessage = function (evt)
{
var received_msg = evt.data;
alert("数据已接收...");
alert("数据:"+received_msg)
}; ws.onclose = function()
{
// 关闭 websocket
alert("连接已关闭...");
};
} else
{
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
}
</script> </head>
<body> <div id="sse">
<a href="javascript:WebSocketTest()">运行 WebSocket</a>
</div> </body>
</html>

演示:

1:

2:

3:

4:

5:

五:如上是简单实现 我们的websocket 例子 ,其中channels来还有如下类型:

 websocket.connect 刚建立连接。

 websocket.disconnect 连接断开的时候

可以根据自己的需求来在routing里定义  在触发websocket各个阶段的时候执行函数。

目前实现的是一个客户端进行操作,也就是说一个consumer的情况,当我们的有多个consumer的时候,怎么保证server端发送消息所有的consumer都能接受到呢?

channels给咱们定义个group概念。也就是说只要consumer和这个组建立的关系,其他的各个consumer都会接受到消息。

consumer.py

 # In consumers.py
from channels import Group # Connected to websocket.connect
def ws_add(message):
message.reply_channel.send({"accept": True})
Group("chat").add(message.reply_channel) # Connected to websocket.receive
def ws_message(message):
Group("chat").send({
"text": "[user] %s" % message.content['text'],
}) # Connected to websocket.disconnect
def ws_disconnect(message):
Group("chat").discard(message.reply_channel)

routing.py:

 from channels.routing import route
from myapp.consumers import ws_add, ws_message, ws_disconnect channel_routing = [
route("websocket.connect", ws_add),
route("websocket.receive", ws_message),
route("websocket.disconnect", ws_disconnect),
]

在浏览器输入如下js:

 // Note that the path doesn't matter right now; any WebSocket
// connection gets bumped over to WebSocket consumers
socket = new WebSocket("ws://" + window.location.host + "/chat/");
socket.onmessage = function(e) {
alert(e.data);
}
socket.onopen = function() {
socket.send("hello world");
}
// Call onopen directly if socket is already open
if (socket.readyState == WebSocket.OPEN) socket.onopen();

我们打开2个浏览器进行测试:

当我们运行窗口二的js的时候窗口也能接受到消息。

这是因为服务端以组来发送消息。

    Group("chat").send({
"text": "[user] %s" % message.content['text'],
})

根据以上特性 我们可以创建我们的聊天室。

其中routing.py中支持正则路径匹配,我们可以根据我们的需求,由用户根据路径不同请求不同的聊天室,想深入了解,请参考官方文档。

为什么研究websocket?

因为在实际生产中,我们需要有一个即时通讯的,不断请求后端结果。来反映在页面。但是,channels测试的过程中,consumer中的函数体不能加入while循环,

测试的结果是:只有当consumer里的函数执行完,才能全部发送到客户端消息,而不是有消息就能发送。

最后的解决方案:只能前端使用计时器同一个tcp连接不断发送消息,服务器端自执行函数触发我们的查询,造成一个伪实时。不知道是否有更好的方法?

django 实现websocket的更多相关文章

  1. Django实现websocket完成实时通讯,聊天室,在线客服等

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

  2. Django实现websocket完成实时通讯、聊天室、在线客服等

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

  3. Django实现websocket完成实时通讯

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

  4. Django实现websocket

    django实现websocket大致上有两种方式,一种channels,一种是dwebsocket.channels依赖于redis,twisted等 一 dwebsocket 1 Django实现 ...

  5. IronFort---基于Django和Websocket的堡垒机

    WebSSH有很多,基于Django的Web服务也有很多,使用Paramiko在Python中进行SSH访问的就更多了.但是通过gevent将三者结合起来,实现通过浏览器访问的堡垒机就很少见了.本文将 ...

  6. Django用websocket实现聊天室之筑基篇

    最近闲来无事,无意发现一个聊天室的前端UI,看着挺好看的但是没有聊天室的通信代码,于是想给它安装电池(通信部分),先看UI: 开始通信部分的工作: 使用的组件: Django1.11.13 chann ...

  7. Django配置websocket请求接口

    1.settings.py INSTALLED_APPS = [ '...', 'channels', '...', ] ASGI_APPLICATION = 'server.routing.appl ...

  8. 11 Django实现WebSocket

    因为需要实时显示状态的需求,想到了websocket,但是Django原生不支持websocket,后来搜索到了chango-channels项目,可以实现次需求. 一.Channels 官方文档 二 ...

  9. 开发基于Django和Websocket的堡垒机

    WebSSH有很多,基于Django的Web服务也有很多,使用Paramiko在Python中进行SSH访问的就更多了.但是通过gevent将三者结合起来,实现通过浏览器访问的堡垒机就很少见了.本文将 ...

随机推荐

  1. Linux scp 后台运行传输文件

    Linux scp 设置nohup后台运行 1.正常执行scp命令 2.输入ctrl + z 暂停任务 3.bg将其放入后台 4.disown -h 将这个作业忽略HUP信号 5.测试会话中断,任务继 ...

  2. Table is specified twice, both as a target for 'UPDATE' and as a separate source

    UPDATE Bins b SET b.ShopSn =’111201611111168706’ WHERE b.Id IN (SELECT b.Id FROM Bins b JOIN BinInve ...

  3. VHDL之concurrent之operators

    Using operators Operators can be used to implement any combinational circuit. However, as will becom ...

  4. Java_Web之神奇的Ajax

    为什么使用Ajax? 无刷新:不刷新整个页面,只刷新局部 无刷新的好处 提供类似C/S的交互效果,操作更方面 只更新部分页面,有效利用带宽   什么是Ajax?   XMLHttpRequest常用方 ...

  5. Apex语言(七)集合

    1.集合 集合是可以存储多个记录数的变量类型. List列表集合可以包含任何数量的数据,与数组类似. Set列表集合包含多个无序的唯一记录数,集合不能具有重复记录,与列表类似. Map地图是一个键值对 ...

  6. LINUX命令行如何查看memcache运行状态

    (附加)如何查看memcache服务器端版本:  ./memcached  -h memcache的运行状态可以方便的用 stats 命令显示. 首先用telnet 127.0.0.1 11211这样 ...

  7. tomcat多实例的部署

    解压部署tomcat程序创建2个实例的工作目录mkdir -p /usr/local/tomcat8_instance/tomcat1mkdir -p /usr/local/tomcat8_insta ...

  8. eas之导入导出

    // 是否仅导出有数据的区域,该方法对所有的导出生效(默认为false)table.getIOManager().setExpandedOnly(true); 输入KDF 如果你已经有了一个完整的KD ...

  9. Node.js+Protractor+vscode搭建测试环境(1)

    1.protractor简介 官网地址:http://www.protractortest.org/ Protractor是一个end-to-end的测试框架,从网络上得到的答案是Protractor ...

  10. hdu 1713求分数的最小公倍数

    题意中的圈数和天数说反了 #include<stdio.h> __int64 gcd(__int64 a,__int64 b) {/* 比如4/3 3/5 通分20/15 9/15 所以这 ...