博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
django 实现websocket
阅读量:5309 次
发布时间:2019-06-14

本文共 3962 字,大约阅读时间需要 13 分钟。

一、简述: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:

1 pip install -U channels

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

配置:

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

1 INSTALLED_APPS = (2     'django.contrib.auth',3     'django.contrib.contenttypes',4     'django.contrib.sessions',5     'django.contrib.sites',6     ...7     'channels',8 )

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

三:概念阐述:

channels: It is an ordered, first-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

 
1 # In consumers.py2 3 def ws_message(message):4     # ASGI WebSocket packet-received and send-packet message types5     # both have a "text" key for their textual data.6     message.reply_channel.send({7         "text": message.content['text'],8     })

 

routing.py

1 # In routing.py2 from channels.routing import route3 from myapp.consumers import ws_message4 5 channel_routing = [6     route("websocket.receive", ws_message),7 ]

 

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

html  code:html5支持websocket。

1  2  3     4    
5 测试websocket 6 7 45 46 47 48 49
52 53 54

演示:

1:

2:

3:

4:

5:

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

1 websocket.connect 刚建立连接。2 3 websocket.disconnect 连接断开的时候

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

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

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

consumer.py

1 # In consumers.py 2 from channels import Group 3  4 # Connected to websocket.connect 5 def ws_add(message): 6     message.reply_channel.send({
"accept": True}) 7 Group("chat").add(message.reply_channel) 8 9 # Connected to websocket.receive10 def ws_message(message):11 Group("chat").send({12 "text": "[user] %s" % message.content['text'],13 })14 15 # Connected to websocket.disconnect16 def ws_disconnect(message):17 Group("chat").discard(message.reply_channel)

 

routing.py:

1 from channels.routing import route2 from myapp.consumers import ws_add, ws_message, ws_disconnect3 4 channel_routing = [5     route("websocket.connect", ws_add),6     route("websocket.receive", ws_message),7     route("websocket.disconnect", ws_disconnect),8 ]

在浏览器输入如下js:

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

 

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

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

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

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

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

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

为什么研究websocket?

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

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

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

 

转载于:https://www.cnblogs.com/caodneg7/p/10446715.html

你可能感兴趣的文章
分治----归并统计逆序对
查看>>
spyder快捷键
查看>>
Python全栈工程师 (类变量、方法、继承、覆盖)
查看>>
python 字符串split()方法
查看>>
Nginx负载均衡
查看>>
DbUtil数据库连接
查看>>
PHP程序对网页表单的处理
查看>>
栅格系统
查看>>
JMS学习八(ActiveMQ消息持久化)
查看>>
MyEclipse 10 中增加插件
查看>>
app版windows95
查看>>
Vue模拟后台数据,proxy代理
查看>>
ADO.Net中有关于连接不上SQL Server的解决办法
查看>>
代码积累与编程能力哪个更重要
查看>>
tomcat,java,jdk verson match
查看>>
spring1冲刺感想与总结
查看>>
多一点学习之外的人文思考
查看>>
xbz分组题B 吉利数字 数位dp入门
查看>>
股票新手入门三阶段
查看>>
C++ char转十六进制
查看>>