Ajax轮询是通过特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种简单粗暴模式有一个明显的缺点,就是浏览器需要不断的向服务器发出请求,HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源(对于很多局域网内的企业应用,这个简单粗暴模式确实解决问题)。

1.1.    websocket简介

  本文接下来采用一种更加高效率的服务端主动推送技术(WebSocket )来提高数据的传输效率。WebSocket通信协议 是 HTML5 开始支持的一种在单个 TCP 连接上进行全双工通讯的协议。在 WebSocket 技术架构中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

  浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。当你获取 Web Socket 连接后,可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。  

1.2.  创建一个Flask-Sockets服务端项目

  本例我们通过VS2019创建一个空的Python项目,来实现Flask-Sockets服务端代码,我们在现有的解决方案里添加一个Project,如下图:

1.2.1. 安装Flask-Sockets组件

Flask我们可采用Flask-Sockets组件来实现websocket 通信验证原型,

组件网址:https://github.com/heroku-python/flask-sockets

安装命令:pip install Flask-Sockets

vs community 我们可以直接在Python Environment 安装Flask-Sockets组件(注意字母大小写,否则不能安装成功),如下图:

1.2.2. 实现websocket服务端源码

服务端先实现由服务端定时推送一个自增的变量值给客户端,代码如下:

from flask import Flask
from flask_sockets import Sockets
import time app = Flask(__name__)
sockets = Sockets(app) @sockets.route('/tagCurValue')
def tagCurValue(ws):
'''
代码模拟每5秒钟,定时给客户端推送一个自增的变量数据
'''
n=0
while not ws.closed:
n=n+1
ws.send(str(n))
print("tag curent value:"+ str(n))
time.sleep(5) @app.route('/')
def hello():
return 'Hello World!' if __name__ == "__main__":
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
server = pywsgi.WSGIServer(('0.0.0.0', 5000), application=app, handler_class=WebSocketHandler)
print('Server Start')
server.serve_forever()  

server = pywsgi.WSGIServer(('0.0.0.0', 5000), application=app, handler_class=WebSocketHandler)

上述代码的'0.0.0.0'要注意赋值,组件的Example例子是一个空字符串,笔者也踩了坑,花费不少时间才找到案例运行失败的原因。

1.2.3. 运行FlaskSocketSvr服务端

首先,我们需要把FlaskSocketSvr设置成解决方案的默认项目,后然F5运行测试环境如下图:

浏览器地址栏输入以下网址:http://127.0.0.1:5000/ 结果如下图:

1.2.4. 重构客户端代码

  现在我们重构客户端代码以便可以访问服务端提高的websocket URL获得数据更新

http://127.0.0.1:5000/tagCurValue

UI JS代码如下:

        //JQuery 代码入口
$(document).ready(function(){ //setInterval("getData()",3000); if ("WebSocket" in window) {
//连接server--TagCurValue
var ws = new WebSocket("ws://127.0.0.1:5000/tagCurValue");
//var ws = new WebSocket("ws://127.0.0.1:8008/tagCurValue");
ws.onmessage = function (evt) {
// 接收数据
receivedMsg = evt.data;
$("#divTag").html(receivedMsg); };
} });

  

现在我们在Project通过Python菜单执行Start server,然后再F5运行服务端,我们就可以通过浏览器运行测试页面了。

测试页面url:http://127.0.0.1:8008/

我们也能通过浏览器的开发工具查看网络访问只发生了一次。

1.3.    读取opc服务的tag位号值

  最后,我们再把tagCurValue'重构成真正读取opc服务某一个tag位号的值。以完成了从UI端到服务端主动获取opc服务tag位号值,并更新UI界面的技术原型。views文件函数tagCurValue'代码修改如下:

@sockets.route('/tagCurValue')
def tagCurValue(ws):
import OpenOPC
while not ws.closed:
opc = OpenOPC.client()
opc.connect('Matrikon.OPC.Simulation')
result= opc['Random.Int1']
opc.close()
ws.send(unicode( result))
print("tag curent value:"+ unicode( result))
time.sleep(5)

现在,我们重新运行测试环境,结果如下图:

1.4.    小结

  本小节介绍了如何通过采用websocket技术,实现由服务端主动Send数据到UI端的通信模式,客户端实时刷新UI端tag位号的当前值,提高了数据传输的效率和性能,样例的FlaskSocketSvr服务也演示了一个独立的服务端到UI端的数据传输方式(独立的服务端地址)。最后,新的服务也通过读取OPC server的tag位号值演示了通过OPC Sever获取监控设备数据的方式。

最新文章

  1. vmstat uptime 系统状态脚本
  2. 模拟赛1030d1
  3. 1、C到C++安全性增强
  4. (三)java的数据类型
  5. gdal中文路径无法打开问题
  6. 【随记】SQL Server连接字符串参数说明
  7. android TextView 垂直滚动 用动画实现
  8. 实现ie6下的居中
  9. UML语言中五大视图和九种图形纵览
  10. Java微服务之Spring Boot on Docker
  11. vue中实现动态切换不同的值
  12. ES6常用语法(下)
  13. Java工程师可以从事的几大职业
  14. GMA Round 1 双曲线与面积
  15. 微信小程序记账本进度二
  16. tensorflow学习之(四)使用placeholder 传入值
  17. js 錯誤
  18. web开发中的跨域整理
  19. flush()的原理
  20. 使用Spring配置动态数据源实现读写分离

热门文章

  1. dotfuscator安装
  2. Sublime Text 2+Zen Coding
  3. MySQL rand(随机数)、floor(保留整数)、char(ASCII 转字符)、concat(字符串连接)
  4. Eclipse无Server或者Tomcat8.5解决办法
  5. curator配置及使用
  6. OSX编译安装Python3及虚拟开发环境Virtualenv
  7. 15.uboot study 串口初始化
  8. iPhone6爆炸真是小概率事件吗?
  9. MySQL占用CPU超过百分之100解决过程
  10. seo搜索优化教程05-SEO常用专业术语