动环监控系统简述

1.术语介绍

1.1 省集中监控中心-Province Supervision Center(PSC)

面向多FSU管理的高级监控层次,即省集中监控中心,通过开放的数据协议,连接监控范围内的FSU。

1.2 现场监控单元-Field supervision unit(FSU)

监控系统的最小管理子系统,由若干监控模块和其它辅助设备组成,面向直接的设备数据采集、处理的监控层次,可以包含采样、数据处理、数据中继等功能,

监控范围一般为一个独立的通信局(站)或大型局(站)内相对独立的电源、空调设备及环境。

1.3 监控对象 Supervision Object(SO)

被监控的各种电源、空调设备及机房环境。

1.4 B接口

为省集中监控中心(PSC)与现场监控单元(FSU)之间的接口。(即FSU的北向接口)

2. 接口网络结构

FSU与PSC之间通过WebService和FTP方式互联,二者同时形成完整的B接口协议标准。


B接口在嵌入式arm监控主机上的实现

环境

宿主机平台:Ubuntu 16.04.6

目标机平台:iMX6UL

交叉编译:gcc-linaro-4.9-2014.11     arm-linux-gnueabihf-gcc        https://www.linaro.org/downloads/

SOAP/XML 关于C/C++ 语言的实现    gsoap_2.8.83      https://sourceforge.net/projects/gsoap2/files/

XML数据的生成和解析       tinyxml2

XML数据的生成和解析   libxml2   ftp://xmlsoft.org/libxml2/

结合主要开发为C环境且尽量占用较少资源,推荐使用minixml

XML数据的生成和解析      minixml   https://www.msweet.org/mxml/


1. gsaop 生成 B接口报文协议 C代码框架

gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。

绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户必须改变程序结构来适应相关的类库。

与之相反,gSOAP利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。

1.1 gsaop在linux下的安装

gsoap安装编译依赖

sudo apt-get install build-essential libgtk2.0-dev libglib2.0-dev checkinstall m4 flex bison automake autoconf openssl libssl-dev

为了成功编译gSOAP,您需要安装GTK+的开发文件和GLib库(libraries)。

安装Checkinstall以便管理您系统中直接由源代码编译安装的软件。

安装YACC,YACC是Unix/Linux上一个用来生成编译器的编译器(编译器代码生成器),sudo apt-get install flex bison

安装OpenSSL,web通信的加密(https)及鉴权  sudo apt-get install openssl libssl-dev

安装编译步骤: 

解压

unzip gsoap_2.8.83.zip
mkdir gsoap_install
cd gsoap-2.8/

配置安装路径、编译、安装

./configure --prefix=/home/wangh/workspace/wh_tools/gsoap_install
sudo make
sudo make install

使用gsoap生成 fsu 代码框架

新建gsoap_fsu文件夹,从gsoap_install文件夹中拷贝以下文件

bin/soapcpp2        bin/wsdl2h

gsoap2.8/gsoap/typemap.dat

custom和import文件夹

1.使用wsdl2h工具,根据WSDL产生头文件,执行以下命令

./wsdl2h -P -x -c -s -t ./typemap.dat -o fsu.h FSUService.wsdl

其中-c为产生纯c代码,默认生成 c++代码;

-x    不产生xml文件(可用可不用,xml有一定帮助,但是太多);

-s为不使用STL库,-t为typemap.dat的标识。

详情可通过wsdl2h.exe -help查看帮助。

这里的WSDL文件,可以在wsdl2h命令中在线下载,也可以先下载到本地,然后引用本地WSDL文件,我这里是采用本地文件方式。

2. 使用soapcpp2工具,根据头文件 fsu.h 产生框架代码,执行以下命令

./soapcpp2 -2 -L -c -x -I import:custom fsu.h

-2    生成 SOAP 1.2

-L    不生成客户端、服务器库文件

-c    为产生纯c代码,默认生成 c++代码

-I path  引用文件路径

3. 提取有效核心代码用于应用编程,应用工程使用文件如下:

2. B接口报文协议分析与实现


2.1 SOAP函数接口分析

根据 FSUService.wsdl 生成 soap API 如下,在 soapStub.h 的最后定义

我们不用去关心 SOAP 接口的实现细节,直接调用对应 API 即可实现客户端与服务器的 xml 数据收发。

客户端接口过程:

soap_call_ns1__invoke() 在客户端调用,实现发送和接收(它调用send和recv);

服务器接口过程:

soap_serve() 服务器调用,部署 SOAP 服务器,它会调用soap_serve_request(),当收到 ns1:invoke 的请求时,

服务器调用 soap_serve_ns1__invoke(),在调用应用层用户接口 ns1__invoke(),来获取接收数据和填充应答数据。

2.2 SOAP通信简单示例

我的工程目录如下图所示:

客户端程序:

/**
**********************************************************************************
* @file main.c
* @brief soap客户端测试程序
* @details 基于东环监控 B 接口的soap客户端程序
* @author wanghuan any question please send mail to 371463817@qq.com
* @date 2019-06-17
* @version V1.0
* @copyright Copyright (c) 2019-2022 江苏亨通光网科技有限公司
**********************************************************************************
*/
#include "soapH.h"
#include "stdsoap2.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "FSUServiceSoapBinding.nsmap" int main(int argc, char **argv)
{
// struct soap fsuSoap;
// soap_init(&fsuSoap); struct soap *fsuSoap = soap_new();
fsuSoap->send_timeout = fsuSoap->recv_timeout = 5; //soap发送、接收超时
fsuSoap->transfer_timeout = 30; //soap消息传输超时
soap_set_namespaces(fsuSoap, namespaces);
// soap_set_mode(fsuSoap, SOAP_C_NOIOB); struct ns1__invokeResponse soap_tmp_ns1__invokeResponse;
char * soap_tmp_SOAP_ENC__string;
soap_default_ns1__invokeResponse(fsuSoap, &soap_tmp_ns1__invokeResponse);
soap_tmp_SOAP_ENC__string = NULL;
soap_tmp_ns1__invokeResponse._invokeReturn = &soap_tmp_SOAP_ENC__string; // 手动组成LOGIN的xml数据字符串
char xmlData[500];
memset(xmlData, 0x00, sizeof(xmlData));
strcat(xmlData, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
strcat(xmlData, "<Request>\n");
strcat(xmlData, "<PK_Type>\n");
strcat(xmlData, "<Name>LOGIN</Name>\n");
strcat(xmlData, "</PK_Type>\n");
strcat(xmlData, "<Info>\n");
strcat(xmlData, "<UserName>123</UserName>\n");
strcat(xmlData, "<PassWord>123</PassWord>\n");
strcat(xmlData, "<FsuId>10004</FsuId>\n");
strcat(xmlData, "<FsuIP>192.168.1.124</FsuIP>\n");
strcat(xmlData, "<FsuPort>10000</FsuPort>\n");
strcat(xmlData, "</Info>\n");
strcat(xmlData, "</Request>\n"); printf("soap_tmp_ns1__invoke._xmlData:\n");
printf("%s", xmlData); // saop 客户端程序
// char * server_addr = "http://10.10.62.83:8080/HT_SC/services/SCService";
char * server_addr = "http://192.168.1.123:8080"; int iRet = soap_call_ns1__invoke(fsuSoap, server_addr, NULL, xmlData, soap_tmp_ns1__invokeResponse._invokeReturn);
if ( iRet == SOAP_ERR)
{
printf("Error while calling the soap_call_ns1__invoke");
}
else
{
printf("Calling the soap_call_ns1__invoke success。\n");
printf("%s\n", *soap_tmp_ns1__invokeResponse._invokeReturn);
} return 0;
}

服务端程序:

/**
**********************************************************************************
* @file main.c
* @brief soap服务端测试程序
* @details 基于东环监控 B 接口的soap服务器程序
* @author wanghuan any question please send mail to 371463817@qq.com
* @date 2019-06-17
* @version V1.0
* @copyright Copyright (c) 2019-2022 江苏亨通光网科技有限公司
**********************************************************************************
*/
#include "soapH.h"
#include "stdsoap2.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "FSUServiceSoapBinding.nsmap" /**
* 启动soap服务器
*/
int main(int argc, char **argv)
{
SOAP_SOCKET iSocket_master, iSocket_slave;
struct soap *fsuSoap = soap_new(); //新建soap fsuSoap->send_timeout = fsuSoap->recv_timeout = 5; //soap发送、接收超时
fsuSoap->transfer_timeout = 30; //soap消息传输超时
// soap_set_mode(fsuSoap, SOAP_C_NOIOB); // saop 服务器程序 8080为端口号,最后一个参数不重要。
iSocket_master = soap_bind(fsuSoap, NULL, 8080, 100); //绑定到相应的IP地址和端口()NULL指本机,然后监听
if (iSocket_master< 0) //绑定出错
{
soap_print_fault(fsuSoap, stderr);
exit(-1);
}
printf("SoapBind success,the master socket number is:%d\n",iSocket_master); //绑定成功返回监听套接字 while(1)
{
iSocket_slave = soap_accept(fsuSoap); //收到套接字连接
if(iSocket_slave < 0)
{
soap_print_fault(fsuSoap, stderr);
exit(-1);
}
//客户端的IP地址
fprintf(stderr,"Accepted connection fromIP= %d.%d.%d.%d socket = %d \n", \
((fsuSoap->ip)>>24)&&0xFF,((fsuSoap->ip)>>16)&0xFF,((fsuSoap->ip)>>8)&0xFF,(fsuSoap->ip)&0xFF,(fsuSoap->socket));
printf("Socket connect success,the slave socket number is:%d\n",iSocket_slave);
soap_serve(fsuSoap);
printf("soap_serve end...");
soap_end(fsuSoap); //服务器出错才到这一步
}
soap_done(fsuSoap);
free(fsuSoap); return 0;
} /**
* soap服务器用户数据处理函数
* @param[in] *_xmlData 接收客户端的xml格式字符串
* @param[out] **_invokeReturn 服务器要回复大数据
* @return SOAP_OK or error code
*/
SOAP_FMAC5 int SOAP_FMAC6 ns1__invoke(struct soap* soap, char *_xmlData, char **_invokeReturn)
{
printf("ns1__invoke _xmlData\n");
printf("%s\n", _xmlData); char xmlData[500];
memset(xmlData, 0, sizeof(xmlData));
strcat(xmlData, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
strcat(xmlData, "<Response>\n");
strcat(xmlData, "<PK_Type>\n");
strcat(xmlData, "<Name>LOGIN_ACK</Name>\n");
strcat(xmlData, "</PK_Type>\n");
strcat(xmlData, "<Info>\n");
strcat(xmlData, "<RightLevel/>\n");
strcat(xmlData, "</Info>\n");
strcat(xmlData, "</Response>"); *_invokeReturn = xmlData;
// *_invokeReturn = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Response>\n<PK_Type>\n<Name>LOGIN_ACK</Name>\n</PK_Type>\n<Info>\n<RightLevel/>\n</Info>\n</Response>"; printf("_invokeReturn _xmlData\n");
printf("%s\n", *_invokeReturn);
return SOAP_OK;
}

程序makefile:

顶层Makefile与Makefile.inc

DIRS :=
DIRS += sc_client
DIRS += sc_server
#DIRS += xml_test # Dummy targets for building and clobbering everything in all subdirectories all:
@ for dir in ${DIRS}; do (cd $${dir}; ${MAKE}) ; done clean:
@ for dir in ${DIRS}; do (cd $${dir}; ${MAKE} clean) ; done

Makefile.inc

SHELL = /bin/bash

#CC           := gcc -m32
#CPP := g++
#LD := ld
#AR := ar
#STRIP := strip CC := arm-linux-gnueabihf-gcc
CPP := arm-linux-gnueabihf-g++
LD := arm-linux-gnueabihf-ld
AR := arm-linux-gnueabihf-ar
STRIP := arm-linux-gnueabihf-strip # -DWITH_DOM -DWITH_OPENSSL两个宏是链接openssl时要用的;
# -DDEBUG宏用于开启SOAP协议收发日志,日志存于文件RECV.log、SENT.log、TEST.log之中
CFLAGS += -c -g -Wall
#CFLAGS += -DWITH_DOM -DWITH_OPENSSL
CFLAGS += -std=gnu99
CFLAGS += -DWITH_NO_C_LOCALE
#CFLAGS += -WITH_NONAMESPACES
CFLAGS += $(INCLUDE) # openssl目录名
OPENSSL_DIR :=
#OPENSSL_DIR += ../openssl # 源文件
SOURCES_FSU :=
SOURCES_FSU += ../soap_sc/soapC.c
SOURCES_FSU += ../soap_sc/soapClient.c
#SOURCES_FSU += ../soap_sc/soapServer.c
SOURCES_FSU += ../soap_sc/stdsoap2.c SOURCES_COMM := # 目标文件
OBJECTS_FSU := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES_FSU)))
OBJECTS_COMM := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES_COMM))) # 头文件路径
INCLUDE += -I../soap_sc/ \
-I../minixml/ \
# -I../libxml2/include \
# -I../tinyxml2/ \
# -I../comm/ \
# -I$(OPENSSL_DIR)/include \ # 共享库链接OpenSSL
#LDLIBS += -L$(OPENSSL_DIR)/lib \
# -lssl \
# -lcrypto \ # 静态库链接OpenSSL
#LDLIBS += $(OPENSSL_DIR)/lib/libssl.a \
# $(OPENSSL_DIR)/lib/libcrypto.a \
# -ldl \ # 静态库链接libxml2
#LDLIBS += ../libxml2/libxml2.a \
# -lm # 静态库链接minixml
LDLIBS += ../minixml/libmxml.a
#LDLIBS += -lmxml # 链接库(其他)
LDLIBS += -lpthread %.o: %.cpp
@echo " CPP " $@;
@$(CPP) $(CFLAGS) -c -o $@ $< %.o: %.c
@echo " CC " $@;
@$(CC) $(CFLAGS) -c -o $@ $< .PHONY: all clean

客户端client的Makefile

include ../Makefile.inc

PROGRAM = fsuc

SOURCES += main.c

OBJECTS := $(patsubst %.c,$(TEMPDIR)%.o,$(filter %.c, $(SOURCES)))

all: $(OBJECTS_FSU) $(OBJECTS_COMM) $(OBJECTS)
$(CC) -o $(PROGRAM) $(OBJECTS_FSU) $(OBJECTS_COMM) $(OBJECTS) $(LDLIBS) clean:
rm -f $(OBJECTS_FSU)
rm -f $(OBJECTS_COMM)
rm -f $(OBJECTS)
rm -f $(PROGRAM)

编译之后 先执行服务端程序,在执行客户端程序

服务端收到request

客户端发送request,并收到response

接下来开始尝试使用 libxml2 库生成和解析 xml

2.3 libxml2安装移植(改用minixml)

新建安装文件夹,这样方便我们提取库文件使用

mkdir /home/wangh/workspace/wh_tools/libxml-install

编写安装及配置脚本 wh_configure.sh 如下:

#!/bin/sh

#sh文件需设置可执行权限 chmod +x wh_configure.sh
#--prefix=PATH,指定make install时目标文件存放路径
PREFIX=/home/wangh/workspace/wh_tools/libxml-install
#--host=target-platform 指定目标平台
HOST=arm-linux
#交叉编译绝对路径
CC_DIR=/home/wangh/Tools/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
#编译配置
#sudo ./configure --prefix=$PREFIX --host=$HOST CC=$CC_DIR --with-python=/home/wangh/workspace/wh_tools/libxml2-2.9.9/python
#编译时由于提示没有python相关的头文件出错,又因为项目中不使用python相关的内容,所以没有讲python进库中,读者应该按照自己的需要要配置该选项。对于zlib同样的道理,--without-zlib不添加会编译出错
sudo ./configure --prefix=$PREFIX --host=$HOST --target=arm CC=$CC_DIR --without-zlib --without-python
sudo make
sudo make install

执行安装脚本

2.4 minixml安装移植

是一个小型的开源的XML解析器,采用 C 语言开发。该解析器最大的特点就是小型、无须依赖其他类库,在嵌入式系统中,minixml解析器很小巧(200k多点),很常用。

待续。。。。。

动环监控系统中B接口的实现的更多相关文章

  1. 无插件纯Web HTML5 3D机房 终结篇(新增资产管理、动环监控等内容)

    原本以为这次的机房资产管理项目告一段落,可以歇一歇,哥还是太天真了.我们伟大的甲方又拿下了第二期的项目,誓把哥的才华发挥到极致啊.国庆长假也没正经休息几天,硬是给人折腾出了个demo,加上了容量管理. ...

  2. 【转】Spark Streaming 实时计算在甜橙金融监控系统中的应用及优化

    系统架构介绍 整个实时监控系统的架构是先由 Flume 收集服务器产生的日志 Log 和前端埋点数据, 然后实时把这些信息发送到 Kafka 分布式发布订阅消息系统,接着由 Spark Streami ...

  3. 日志监控系统中,大批量查询mysql方案

    最近开发遇到一个问题:需要查询一个大时间段内的数据,分1000个小段,即为1000个点.X轴是时间,Y轴是该小时间段内统计后数据.注意:数据返回是一个list,其中每个对象返回值都是该小时间段内数据统 ...

  4. 开源监控系统中 Zabbix 和 Nagios 哪个更好?

    监控平台的话,各有优劣,但基本都可以满足需求.等达到一定监控指标后,发现,最困难的是监控项目的管理. CMDB中小规模(服务器<=1k):Zabbix大规模(1k>=服务器<=10k ...

  5. ClickHouse在监控系统中的应用

    一.背景 这个项目是一个监控系统,主要监控主机.网络设备.应用等.主机监控的数量有1500台左右,数量还在不断增长,加上网络设备和应用,目前总共监控的指标达到近40万个. 二.问题 一开始为了快速交付 ...

  6. 使用API接口在zabbix系统中登陆、创建、删除agent

    一.API的介绍 API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力 ...

  7. 机房-动环-江森ODS系统

    优势: 标准的BACnet系统平台 开放的集成特性 支持Desktop and Server平台 支持多达100个NxE 支持无线应用,可以手机访问 DCIM---数据中心基础架构管理平台介绍 不同于 ...

  8. 李学斌:论复杂系统中的应用间协作V3

    说明 本文主要讨论了巨型复杂业务系统的一种构建思路,力图实现决策意志的快速.准确.一致的下传并简化实施成本提供实施效率.通过全业务领域的即时流程编排,实现全网业务IT系统的快速建设与迭代.本文所讲的方 ...

  9. Ganglia+Nagios监控系统

    第1章 简介 ganglia是一款为HPC(高性能计算) 集群设计的可扩展性 的分布式监控系统,它可以监视和显示集群中节点的各种状态信息,他由运行在各个节点上的gmond守护进程来采集 CPU.内存. ...

随机推荐

  1. 🔥 LeetCode 热题 HOT 100(11-20)

    20. 有效的括号 class Solution { public boolean isValid(String s) { Map<Character, Character> map = ...

  2. SQL语句(二)数据排序和单行函数

    目录 一.排序查询 1. 基本排序 2. 多条件排序 二.单行函数 调用方法 字符函数 ①LENGTH函数 ②CONCAT函数 ③upper 和 lower ④substr ⑤instr ⑥trim ...

  3. Android太太太太太卷了,累了

    我们聊到互联网行业的时候,一个不可避免的话题就是"内卷",而在程序员这个群体中,Android,绝对是卷得最厉害的. 毕竟前几年Android兴起的时候,入门门槛低,培训机构培养了 ...

  4. Shell-03-表达式和运算符

    表达式和运算符 条件表达式语句 [ 1 -eq 1 ] [[ 1 -eq 1 ]] test 1 -eq 1 等同于 [ 1 -eq 1 ] [root@satest_192-168-3-121 sh ...

  5. Longhorn 企业级云原生分布式容器存储-券(Volume)和节点(Node)

    内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生分布式块存储解决方案设计架构和概念 Longhorn 企业级云原生容器存储解决方 ...

  6. 记面试的一道JS题

    给一个数组arr=[1,2,3,4,5],索引第二位插入'z',设计一个函数change,调用change(arr, 2, 'z')返回一个新数组[1,2,'z',3,4,5] 我想了两种办法: 第一 ...

  7. 题解 Dove 打扑克

    传送门 考场上觉得复杂度是假的就没怎么优化,然后考完题解帮我证明了它是真的-- 首先合并可以用并查集维护,可以顺便维护出集合的大小 对于操作2,发现如果 \(size_i\) 是确定的,可以用权值线段 ...

  8. Mysql5.6.47开放远程访问(修改远程访问密码)

    1.登录mysql mysql -u root -p 然后输入密码,登录进去mysql: 2.切换数据库 use mysql; 3.修改权限 GRANT ALL PRIVILEGES ON *.* T ...

  9. 什么?都1202年了还不懂k8s和容器的关系?!这份k8s指南快拿走不谢!

    都1202年了,还是有许多人搞不清容器与k8s之间的关系.在开始本篇正文之前,我们先来捋一捋这对"CP"的关系. 你可能已经很熟悉虚拟机了,最常见的莫过于我们拿到macOS却需要用 ...

  10. 无法加载文件 E:\PROGRAM FILES\NODEJS\NODE_GLOBAL\yarn.ps1,因为在此系统中禁止执行脚本

    参考: npm : 无法加载文件 C:\Program Files\nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本.