本小节继续演示如何在Django项目中采用早期websocket技术原型来实现把OPC服务端数据实时推送到UI端,让监控页面在另一种技术方式下,实时显示现场设备的工艺数据变化情况。本例我们仍然采用比较轻量级的dwebsocket组件。

1. 安装dwebsocket组件

  安装命令:pip install dwebsocket  

1.1. dwebsocket使用方法

  如果你想为一个单独的视图处理一个websocket连接可以使用accept_websocket装饰器,它会将标准的HTTP请求路由到视图中。使用require_websocke装饰器只允许使用WebSocket连接,会拒绝正常的HTTP请求。

  在设置中添加设置MIDDLEWARE_CLASSES=dwebsocket.middleware.WebSocketMiddleware这样会拒绝单独的视图使用websocket,必须加上accept_websocket 装饰器。

  设置WEBSOCKET_ACCEPT_ALL=True可以允许每一个单独的视图实用websockets

1.2. 常用方法和属性

  1.request.is_websocket()  如果是个websocket请求返回True,如果是个普通的http请求返回False,可以用这个方法区分它们。

  2.request.websocket  在一个websocket请求建立之后,这个请求将会有一个websocket属性,用来给客户端提供一个简单的api通讯,如果request.is_websocket()是False,这个属性将是None。

  3.WebSocket.wait()  返回一个客户端发送的信息,在客户端关闭连接之前他不会返回任何值,这种情况下,方法将返回None

  4.WebSocket.read()  如果没有从客户端接收到新的消息,read方法会返回一个新的消息,如果没有,就不返回。这是一个替代wait的非阻塞方法

  5.WebSocket.count_messages()  返回消息队列数量

  6.WebSocket.has_messages()  如果有新消息返回True,否则返回False

  7.WebSocket.send(message)  向客户端发送消息

  8.WebSocket.__iter__()  websocket迭代器

  dwebsocket使用起来比较简单,增加一个简单的服务端url和重构UI代码;UI代码创建一个websocket连接并在onmessage 事件里处理返回的数据即可,不用花费多大的代价就能快速让监控页面升级到一个新的方式下,下面看代码演进吧。

2.重构服务端代码——增加一个推送的websocket url

  使用accept_websocket装饰器在Collector APP的views文件中增加一个pushCollector的方法,实现UI端连接上服务端后,服务端使用websocket主动向UI界面推送实时设备工艺数据,函数代码如下:

from dwebsocket.decorators import accept_websocket
import OpenOPC
@accept_websocket
def pushCollectorData(request): tank4C9={
'DeviceId': 1,
'DeviceName':'1#反应罐',
'Status': 0, #设备运行状态
'OverheadFlow':0 ,#'顶流量',
'ButtomsFlow': 0, #'低流量'
'Power': 0, #功率
}
Collector={
'CollectorId': 1,
'CollectorName':'1#采集器',
'Status': 0,
'DeviceList':[tank4C9],
}
Collector={
'CollectorId': 1,
'CollectorName':'1#采集器',
'Status': 0,
'DeviceList':[tank4C9],
} if request.is_websocket():
try:
while True: opc = OpenOPC.client()
opc.connect('Matrikon.OPC.Simulation')
tank4C9['OverheadFlow']= opc['Random.Int1']
tank4C9['ButtomsFlow']= opc['Random.Int2']
tank4C9['Power']= opc['Random.Int4']
opc.close()
request.websocket.send(\
json.dumps( {"rows":[Collector],'total':1}))
time.sleep(2) finally:
client.disconnect()

  解读:上文代码与原来的主要差别就是从被动刷新(UI请求后)读去opc服务的tag位号值,变成间隔time.sleep(2)秒读取数据后通过request.websocket.send到UI端。

3. 重构UI端代码

  这里django与Flask的差别就是无须新建一个新的项目,当前项目我们就可以通过重构tank4C9.html页面代码来使用websocket实时推送功能。

  重构后tank4C9.html代码如下:

<html>
<head><title></title>
<script src="https://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head> <body> <div>
Status: <strong id="divStatus">0</strong>
</div>
<div>
OverheadFlow: <strong id="divOverheadFlow">0</strong>
</div>
<div>
ButtomsFlow: <strong id="divButtomsFlow">0</strong>
</div>
<div>
Power: <strong id="divPower">0</strong>
</div> <div>
pushCount: <strong id="divpushCount">0</strong>
</div> <script>
//JQuery 代码入口
$(document).ready(function(){ if ("WebSocket" in window) {
//连接server--TagCurValue
var ws = new WebSocket("ws://127.0.0.1:8090/pushCollector/");
ws.onmessage = function (evt) {
// 接收数据
d = JSON.parse(evt.data);
collector= d.rows[0]
for (i = 0; i < collector.DeviceList.length; i++){
device = collector.DeviceList[i]
$("#divStatus").html(device.Status);
$("#divOverheadFlow").html(device.OverheadFlow);
$("#divButtomsFlow").html(device.ButtomsFlow);
$("#divPower").html(device.Power);
$("#divpushCount").html(device.Count); } };
}
}); </script> </body>
</html>

  解读:UI端代码通过ws.onmessage事件更新页面显示,对照上一张的ajax轮询模式的代码,代码的主体结构和功能并没有大的变化,只是采用了一种的新的数据传递方式而已。

  注意

  var ws = new WebSocket("ws://127.0.0.1:8090/pushCollector/");

  pushCollector/ url最后那个“/”,这个点是django与flask的一个差别,否则我们创建这个websocket时会收到301错误提示!

4. 发布pushCollectorData url

  项目的urls发布这新的url接口地址,这例我们保留原来的getCollectorData,代码如下:

# Uncomment next two lines to enable admin:
#from django.contrib import admin from django.urls import path
from Collector import views urlpatterns = [
# Uncomment the next line to enable the admin:
#path('admin/', admin.site.urls) path('tank4C9/', views.tank4C9),
path('getCollectorData/', views.getCollectorData),
path('pushCollectorData/', views.pushCollectorData), ]

4. 调试运行效果

5. 小结

  本小节我们通过websocket的主动推送方式,完成了实时监控画面从后台服务端主动推送到UI端的技术架构迭代,这个过程我们也演示了项目迭代的方式,迭代推进项目功能点的好处非常明显也就是在一个版本满足需求的前提下,可以相对从容的采用新的技术和方案升级产品改进性能。

  例子我们保留了原来的getCollectorData url,实际的项目开发也是通过增加新推送方法的方式来组织进行的,这样新的升级也同时满足原有ajax模式的后台访问方式。从而避免升级过程中,前后台升级版本不一致导致原有页面不能正常访问,避免系统已发布就“崩溃”的“灾难”问题。

  这里多说一下敏捷编程下的“小步快跑,快速迭代”模式下,一些团队遇到的问题就是一开始极简设计满足当下要求,然后在不断功能迭代过程中项目产品架构技术快速老化,可是团队还是不断的增加功能点,而没有人员关心技术架构优化和调整。最终,导致问题越积越多,架构越来越难用,产品构建越来越慢,最后等待一次彻底的项目“重构”。一些“好的”项目应该在过程中逐步演化代码结构来满足不断扩张的功能需求。

  敏捷编程的前提是要有一套体系来做保证的,需求管理、代码重构、单元测试等等,比如:代码重构在敏捷编程项目过程中就非常重要,一开始简单满足需求,一旦发现引入新的需求代码不能很好的满足需求的变化时,引入好的设计模式,采用代码重构的方式来优化代码结构,并通过回归单元测试来保证新的代码结构能够正常通过原来的单元测试。盲目的采用敏捷编程又没有采用它有效管理的一整套机制,最后陷入项目泥潭的,只能说是没有理解好“敏捷”的核心要素罢了。

Python工业互联网监控项目实战3—websocket to UI的更多相关文章

  1. python工业互联网监控项目实战5—Collector到opcua服务

    本小节演示项目是如何从连接器到获取Tank4C9服务上的设备对象的值,并通过Connector服务的url返回给UI端请求的.另外,实际项目中考虑websocket中间可能因为网络通信等原因出现中断情 ...

  2. python工业互联网监控项目实战2—OPC

    OPC(OLE for Process Control)定义:指为了给工业控制系统应用程序之间的通信建立一个接口标准,在工业控制设备与控制软件之间建立统一的数据存取规范.它给工业控制领域提供了一种标准 ...

  3. python工业互联网监控项目实战4—python opcua

    前面章节我们采用OPC作为设备到上位的信息交互的协议,本章我们介绍跨平台的OPC UA.OPC作为早期的工业通信规范,是基于COM/DCOM的技术实现的,用于设备和软件之间交换数据,最初,OPC标准仅 ...

  4. Python爬虫开发与项目实战

    Python爬虫开发与项目实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1MFexF6S4No_FtC5U2GCKqQ 提取码:gtz1 复制这段内容后打开百度 ...

  5. Python爬虫开发与项目实战pdf电子书|网盘链接带提取码直接提取|

    Python爬虫开发与项目实战从基本的爬虫原理开始讲解,通过介绍Pthyon编程语言与HTML基础知识引领读者入门,之后根据当前风起云涌的云计算.大数据热潮,重点讲述了云计算的相关内容及其在爬虫中的应 ...

  6. python工业互联网应用实战2—从需求开始

    前言:随着国家工业2025战略的推进,工业互联网发展将会提速,将迎来一个新的发展时期,越来越多的企业开始逐步的把产线自动化,去年年底投产的小米亦庄的智能工厂就是一个热议的新闻.小米/华为智能工厂只能说 ...

  7. python工业互联网应用实战3—模型层构建

    本章开始我们正式进入到实战项目开发过程,如何从需求分析获得的实体数据转到模型设计中来,变成Django项目中得模型层.当然,第一步还是在VS2019 IDE环境重创建一个工程项目,本文我们把工程名称命 ...

  8. python工业互联网应用实战1—SQL与ORM

    从sql到ORM应该说也是编程体系逐步演化的结果,通过类和对象更好的组织开个过程中遇到的各种业务问题,面向对象的解耦和内聚作为一套有效的方法论,对于复杂的企业应用而言确实能够解决实践过程中很多问题. ...

  9. python工业互联网应用实战18—前后端分离模式之jquery vs vue

    前面我们分三章来说明了使用django template与jquery的差别,通过jquery如何来实现前后端的分离,同时再9章节使用vue.js 我们浅尝辄止的介绍了JQuery到vue的切换,由于 ...

随机推荐

  1. MassDNS:跨域DNS枚举工具

    MassDNS:跨域DNS枚举工具 simeon 原文地址:http://offsecbyautomation.com/Use-MassDNS/ 工具地址:https://github.com/ble ...

  2. ElasticSearch 32766 的限制

    插入一个稍大的数据到elasticsearch的时候,突然报错“ 400 - elastic: Error 400 (Bad Request): Document contains at least ...

  3. Centos单机部署Elasticsearch7.2集群

    配置node0 # ======================== Elasticsearch Configuration ========================= # # NOTE: E ...

  4. 汉诺塔Java实现

    public class Hanoi { public static void main(String[] args ) { Hanoi hanoi = new Hanoi(); hanoi.hano ...

  5. 在C 中加载TorchScript模型

    本教程已更新为可与PyTorch 1.2一起使用 顾名思义,PyTorch的主要接口是Python编程语言.尽管Python是合适于许多需要动态性和易于迭代的场景,并且是首选的语言,但同样的,在 许多 ...

  6. POJ-3134-Power Calculus(迭代加深)

    题意:输入一个n,问x从1次方开始,到n次方 ,可以乘或除已经计算出来的数 ,最少需要执行多少步? 思路:迭代加深 ,深度从0开始 ,直到返回值为真. 在深搜过程中剪枝(深度的判断 ,当前最大值尽全力 ...

  7. coding++:Spring IOC/DI 实现原理

    什么是 SpringIOC: spring ioc 指的是控制反转,IOC容器负责实例化.定位.配置应用程序中的对象及建立这些对象间的依赖.交由Spring容器统一进行管理,从而实现松耦合. “控制反 ...

  8. Dubbo与Spring Cloud的比较

    区别: ----- 来源(背景): Dubbo,是阿里巴巴服务化治理的核心框架,并被广泛应用于阿里巴巴集团的各成员站点. Spring Cloud,从命名我们就可以知道,它是Spring Source ...

  9. BurpSuit工具安装和基本使用方法

    burpsuite是渗透的必备工具,使用它可以进行一些截包分析,修改包数据.暴力破解.扫描等功能,使用最多的场景应该是设置代理拦截数据包分析数据和爆破. JDK工具下载和安装(可选) 运行BurpSu ...

  10. 【tensorflow2.0】处理图片数据-cifar2分类

    1.准备数据 cifar2数据集为cifar10数据集的子集,只包括前两种类别airplane和automobile. 训练集有airplane和automobile图片各5000张,测试集有airp ...