使用go-zero微服务框架实现云监控后台(三.c语言操作cJson封装,json和结构体互转)

本文涉及的产品
云监控,每月短信1000条
简介: 使用go-zero微服务框架实现云监控后台(三.c语言操作cJson封装,json和结构体互转)

c语言操作cJson封装,以及json和结构体互转。如果不做封装直接操作cJSON有点儿繁琐。


所以封装下是很有必要的,使用起来简单好用多了。


这是我计划的终端状态监控服务的终端部分的模块组件。


终端应用程序定时更新状态文件,应用中跑的另一个后台服务则定时读取该状态文件并上送至后台服务。以此无耦合的实现对终端的状态监控。参见:终端出厂后自动化运维方案_独行猫A 的沉淀、积累、总结。天天学习,好好向上...linux,Android,Vue,Go)-CSDN博客


下面是c语言读写json文件的简单封装,完成c语言结构体到json文件,json到结构体的转换。


#include "jsonopt.h"
/**
 * Function:GetArrayValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中获取ArrayItem内容
 */
int GetArrayValueString(cJSON* json,int id, char* name, char* param){
    cJSON* node;
    node = cJSON_GetArrayItem(json,id);
    if(!node){
        return -1;
    }
    sprintf(param, "%s", cJSON_GetObjectItem(node, name)->valuestring);
    return 0 ;
}
/**
 * Function:GetValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中读取字符串内容
 */
char* GetValueString(cJSON* json,char* name){
  cJSON* pObj = NULL;
    pObj = cJSON_GetObjectItem(json,name);
    if(pObj != NULL){
      return pObj->valuestring;
    }else{
      return NULL;
    }
}
/**
 * Function:GetValueInt
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中读取int类型值
 */
int GetValueInt(cJSON* json,char* name){
  cJSON* pObj = NULL;
    pObj = cJSON_GetObjectItem(json,name);
    if(pObj != NULL){
      return pObj->valueint;
    }else{
      return 0;
    }
}
/**
 * Function:SetValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 向json中的String类型字段赋值
 */
int SetValueString(cJSON* json,char* name,char* value){
  //printf("set key:%s,val:%s\n",name,value);
  if(cJSON_GetObjectItem(json,name)->valuestring != NULL){
    cJSON_ReplaceItemInObject(json,name,cJSON_CreateString(value));
  }else{
    //cJSON_AddItemToObject(json, name, cJSON_CreateString(value)); 
    cJSON_AddStringToObject(json, name, value);  
  }
  return 0;
}
/**
 * Function:SetValueInt
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 向json中的Int类型字段赋值
 */
int SetValueInt(cJSON* json,char* name,int value){
  cJSON* pObj = NULL;
  pObj = cJSON_GetObjectItem(json,name);
  if(pObj != NULL){
    pObj->valueint = value;
    pObj->valuedouble = value;
    return 0;
  }else{
    cJSON_AddNumberToObject(json, name, value); 
  }
  return 0;
}


/**
   * Copyright (C), 2021-2021,yangyongzhen 
   * File name:  jsonopt.h 
   * Author:   yangyongzhen
   * Version:  0.1
   * Date:                   2021-11-11 
   * Description:   c语言的cJSON操作封装
 **/
#ifndef _JSON_OPT_H_
#define _JSON_OPT_H_
#include <string.h>
#include "cJSON.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
 * Function:S2J_setInt
 * Description:Struct向Json的Int类型赋值
 * */
#define S2J_setInt(json,stru,element) SetValueInt(json,#element,(stru)->element)  
/**
 * Function:S2J_setString
 * Description:Struct向Json的String类型赋值
 * */
#define S2J_setString(json,stru,element) SetValueString(json,#element,(stru)->element)  
/**
 * Function:J2S_getString
 * Description:Json向Struct中的String类型赋值
 * */
#define J2S_getString(json,stru,element) {char *item=NULL; item = GetValueString(json,#element); if(item!=NULL){strcpy((stru)->element,item);}}
/**
 * Function:J2S_getInt
 * Description:Json向Struct中的Int类型赋值
 * */
#define J2S_getInt(json,stru,element) (stru)->element = GetValueInt(json,#element)
/**
 * Function:GetArrayValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中获取ArrayItem内容
 */
extern int GetArrayValueString(cJSON* json,int id, char* name, char* param);
/**
 * Function:GetValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中读取字符串内容
 */
extern char* GetValueString(cJSON* json,char* name);
/**
 * Function:GetValueInt
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 从json中读取int类型值
 */
extern int GetValueInt(cJSON* json,char* name);
/**
 * Function:SetValueString
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 向json中的String类型字段赋值
 */
extern int SetValueString(cJSON* json,char* name,char* value);
/**
 * Function:SetValueInt
 * Data:2021-11-11
 * Author:yangyongzhen
 * Description: 向json中的Int类型字段赋值
 */
extern int SetValueInt(cJSON* json,char* name,int value);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif


使用方法举例:


#include "jsonopt.h"
static cJSON* root;
PosStatus posStatus;
/**
从json文件中加载信息到结构体
*/
int LoadStatus(PosStatus *status){
  printf("LoadStatus ENTER\n");
  root = GetJsonObject(STATUS_FILE_NAME);
  char * out = cJSON_Print(root);
  printf("LoadStatus:json=%s\n",out);
    if(out == NULL){
        printf("LoadStatus error,no json data\n");
        return -1;
    }
  J2S_getString(root,status,sn);
  printf("[item] = %s\n",status->sn);
    J2S_getString(root,status,posno);
  printf("[item] = %s\n",status->posno);
  J2S_getString(root,status,city);
  printf("[item] = %s\n",status->city);
  J2S_getString(root,status,tyid);
  printf("[item] = %s\n",status->tyid);
  J2S_getString(root,status,sver);
  printf("[item] = %s\n",status->sver);
  J2S_getString(root,status,ctime);
  printf("[item] = %s\n",status->ctime);
    //item = GetValueString(root,"posno");
    //if(item != NULL){
    //    strcpy(status->posno,item);
    //    printf("[item] = %s\n",status->posno);
    //}
  return 0;
}
/**
结构体信息保存为json文件
*/
int SaveStatus(PosStatus status){
  char * out = NULL;
    printf("SaveStatus ENTER\n");
  if(root == NULL){
    printf("SaveStatus error\n");
    return -1;
  }
  S2J_setString(root,&status,sn);
  S2J_setString(root,&status,posno);
  S2J_setString(root,&status,tyid);
  S2J_setString(root,&status,city);
  S2J_setString(root,&status,sver);
  S2J_setInt(root,&status,unum1);
  S2J_setInt(root,&status,unum2);
  S2J_setInt(root,&status,amount);
  S2J_setInt(root,&status,count);
  S2J_setInt(root,&status,line);
  S2J_setString(root,&status,carno);
  S2J_setString(root,&status,jd);
  S2J_setString(root,&status,wd);
  S2J_setInt(root,&status,alarm);
  S2J_setInt(root,&status,pver);
  S2J_setInt(root,&status,bver);
  S2J_setString(root,&status,empid);
  S2J_setString(root,&status,rvs1);
  S2J_setString(root,&status,rvs2);
  S2J_setString(root,&status,stime);
  S2J_setString(root,&status,ctime);
  S2J_setInt(root,&status,tenant);
  //SetValueString(root,"carno",status.carno);
  //SetValueString(root,"jd",status.jd);
  //SetValueString(root,"wd",status.wd);
  printf("SaveStatus end\n");
  out = cJSON_Print(root);
  writeFile(STATUS_FILE_NAME,out);
  printf("SetStatus:json=%s\n",out);
  return 0;
}


//status.h头文件
#ifndef _STATUS_H_
#define _STATUS_H_
#include  "cJSON/cJSON.h"
//保存位置 终端状态监控文件存储位置
#define STATUS_FILE_NAME  "../opt/status.json"
//#define STATUS_FILE_NAME  "./status.json"
//终端设备状态信息
typedef struct _PosStatus{
  char sn[32];     //设备唯一号
    char posno[16];  //终端编号
    char city[10];   //城市代码
    char tyid[10];   //终端类型
    char sver[32];   //终端版本号
    int  unum1;      //未传记录数量--公交
    int  unum2;      //未传记录数量--三方
    char ndate[16];  //当前日期
    char ntime[16];  //当前时间
    int  amount;     //当班总额
    int  count;      //当班人数
    int  line;       //线路号
    char carno[16];  //车辆编号
    char jd[20];     //经度
    char wd[20];     //维度
    int  alarm;      //设备报警码
    char stime[16];  //开机时间
    char ctime[16];  //关机时间
    int  tenant;     //租户ID
}PosStatus;
extern PosStatus posStatus;
extern int LoadStatus(PosStatus *status);
extern int SaveStatus(PosStatus status);
extern int SetValueInt(cJSON* root,char* name,int value);
extern int SetValueString(cJSON* root,char* name,char* value);
extern char* GetValueString(cJSON* json,char* name);
extern int GetValueInt(cJSON* json,char* name);
extern cJSON* GetJsonObject(char* fileName);
extern int writeFile(char *filename,char *data);
#endif


static.c文件内容:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "status.h"
static cJSON* root;
PosStatus posStatus;
/**
从文件中读取json信息到结构体
*/
int LoadStatus(PosStatus *status){
  root = GetJsonObject(STATUS_FILE_NAME);
  char * out = cJSON_Print(root);
  printf("LoadStatus:json=%s\n",out);
    if(out == NULL){
        printf("LoadStatus error,no json data\n");
        return -1;
    }
    char * item = NULL;
    item = GetValueString(root,"sn");
    if(item != NULL){
        strcpy(status->sn,item);
        printf("[item] = %s\n",status->sn);
    }
    item = GetValueString(root,"posno");
    if(item != NULL){
        strcpy(status->posno,item);
        printf("[item] = %s\n",status->posno);
    }
    item = GetValueString(root,"city");
    if(item != NULL){
        strcpy(status->city,item);
        printf("[item] = %s\n",status->city);
    }
    item = GetValueString(root,"tyid");
    if(item != NULL){
        strcpy(status->tyid,item);
        printf("[item] = %s\n",status->tyid);
    }
    item = GetValueString(root,"sver");
    if(item != NULL){
        strcpy(status->sver,item);
        printf("[item] = %s\n",status->sver);
    }
  return 0;
}
/**
结构体信息写入json文件
*/
int SaveStatus(PosStatus status){
  char * out = NULL;
    printf("SaveStatus ENTER\n");
  if(root == NULL){
    printf("SaveStatus error\n");
    return -1;
  }
    SetValueString(root,"sn",status.sn);
    SetValueString(root,"posno",status.posno);
    SetValueString(root,"tyid",status.tyid);
  SetValueString(root,"city",status.city);
    SetValueString(root,"sver",status.sver);
  SetValueInt(root,"unum1",status.unum1);
    SetValueInt(root,"unum2",status.unum2);
    SetValueInt(root,"amount",status.amount);
    SetValueInt(root,"count",status.count);
    SetValueInt(root,"line",status.line);
  SetValueString(root,"carno",status.carno);
    SetValueString(root,"jd",status.jd);
    SetValueString(root,"wd",status.wd);
    SetValueInt(root,"alarm",status.alarm);
    SetValueString(root,"stime",status.stime);
    SetValueString(root,"ctime",status.ctime);
    SetValueInt(root,"tenant",status.tenant);
  out = cJSON_Print(root);
  writeFile(STATUS_FILE_NAME,out);
  printf("SetStatus:json=%s\n",out);
  return 0;
}
int writeFile(char *filename,char *data){
  FILE *fp = NULL;
  fp = fopen(filename,"w+");
  if(fp == NULL){
    fprintf(stderr,"open file failed\n");
    return -1;
  }
  fprintf(fp,"%s",data);
  if(fp != NULL){
    fclose(fp);
  }
  return 0;
}
cJSON* GetJsonObject(char* fileName){
    long len;
    char* pContent;
    int tmp;
    cJSON* json;
    FILE* fp = fopen(fileName, "rb+");
    if(!fp){
        printf("open file error\n");
        return NULL;
    }
    printf("open file success\n");
    fseek(fp,0,SEEK_END);
    len=ftell(fp);
    if(0 == len){
        printf("file len is 0\n");
        return NULL;
    }
    fseek(fp,0,SEEK_SET);
    pContent = (char*) malloc (sizeof(char)*len);
    tmp = fread(pContent,1,len,fp);
    fclose(fp);
    json = cJSON_Parse(pContent);
    if (!json)
    {
        free(pContent);
        return NULL;
    }
    free(pContent);
    printf("read file ok\n");
    return json;
}
//读取cJSON索引为index的结点某个key值对应的value,索引从0开始
int GetArrayValueString(cJSON* json,int id, char* name, char* param){
    cJSON* node;
    node = cJSON_GetArrayItem(json,id);
    if(!node){
        return -1;
    }
    sprintf(param, "%s", cJSON_GetObjectItem(node, name)->valuestring);
    return 0 ;
}
char* GetValueString(cJSON* json,char* name){
  cJSON* pObj = NULL;
    pObj = cJSON_GetObjectItem(json,name);
    if(pObj != NULL){
      return pObj->valuestring;
    }else{
      return NULL;
    }
}
int GetValueInt(cJSON* json,char* name){
  cJSON* pObj = NULL;
    pObj = cJSON_GetObjectItem(json,name);
    if(pObj != NULL){
      return pObj->valueint;
    }else{
      return 0;
    }
}
int SetValueString(cJSON* json,char* name,char* value){
  strcpy(cJSON_GetObjectItem(json,name)->valuestring,value);
  return 0;
}
int SetValueInt(cJSON* json,char* name,int value){
  cJSON_GetObjectItem(json,name)->valueint = value;
  cJSON_GetObjectItem(json,name)->valuedouble = value;
  return 0;
}
/*
int main(){
  printf("cjson test,read and save\n");
  LoadStatus(&posStatus);
    strcpy(posStatus.sver,"NC_B503_YYZ");
    posStatus.alarm = 6;
    posStatus.amount = 10;
    posStatus.count = 12;
    strcpy(posStatus.posno,"413101010E");
  SaveStatus(posStatus);
}
*/


生成的json文件如:


{
  "sn": "00a0c6000023",
  "posno":"413101010E",
  "city": "",
  "tyid": "",
  "sver": "NC_B503_YYZ",
  "unum1":  0,
  "unum2":  0,
  "ndate":  "2021-08-11",
  "ntime":  "17:20:30",
  "amount": 10,
  "count":  12,
  "line": 0,
  "carno":  "",
  "jd": "",
  "wd": "",
  "alarm":  6,
  "stime":  "",
  "ctime":  "",
  "tenant": 0
}


附带一个终端开机自启动脚本startmonitor.sh:


#!/bin/bash
fileName="/app/city_app/opt/monitor"
buzzGPIO="/sys/class/gpio/gpio15"
#enable buzzse for notifying success
function beep_notify()
{
   if [ ! -d "$buzzGPIO" ]; then
        echo 15 > /sys/class/gpio/export
   fi
   if [ -d "$buzzGPIO" ]; then
        echo "out" > "/sys/class/gpio/gpio15/direction"
        echo "1" > "/sys/class/gpio/gpio15/value"
        sleep 1
        echo "0" > "/sys/class/gpio/gpio15/value"
   fi
}
function CheckProcess()
{
  PROCESS_NUM=`ps | grep "$1" | grep -v "grep" | wc -l`
  return $PROCESS_NUM
}
if [ ! -f $fileName ]; then  
      echo "error!monitor file not exit!"
        exit 1
    else 
  echo "find monitor file,begin start..."
    CheckProcess qrlinux
    if [ $? -eq 0 ];then
    echo "no monitor progress find!"
    else
    echo "find monitor,..."
      killall -9 monitor
        sleep 1
        fi 
        cd /app/city_app/opt/
      ./monitor -monitorcfg=./monitorcfg.ini &  
      echo "start ok"
      beep_notify
      exit 0
fi


终端开机自启动服务应用的方法:


system("killall -9 monitor");
 system("../opt/startmonitor.sh");
相关实践学习
基于云监控实现的监控系统
通过阿里云云监控功能给非阿里云主机安装监控插件,从而实现对非阿里云主机的各项指标进行监控和管理,在配置报警规则和报警人的情况下,能对特定的场景做出报警反应通知到报警人的手机上。
相关文章
|
1月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
101 3
|
1月前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
2月前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
|
2月前
|
Kubernetes Java Android开发
用 Quarkus 框架优化 Java 微服务架构的设计与实现
Quarkus 是专为 GraalVM 和 OpenJDK HotSpot 设计的 Kubernetes Native Java 框架,提供快速启动、低内存占用及高效开发体验,显著优化了 Java 在微服务架构中的表现。它采用提前编译和懒加载技术实现毫秒级启动,通过优化类加载机制降低内存消耗,并支持多种技术和框架集成,如 Kubernetes、Docker 及 Eclipse MicroProfile,助力开发者轻松构建强大微服务应用。例如,在电商场景中,可利用 Quarkus 快速搭建商品管理和订单管理等微服务,提升系统响应速度与稳定性。
70 5
|
2月前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
74 2
|
2月前
|
Cloud Native 安全 Java
Micronaut对决Spring Boot:谁是微服务领域的王者?揭秘两者优劣,选对框架至关重要!
【9月更文挑战第5天】近年来,微服务架构备受关注,Micronaut和Spring Boot成为热门选择。Micronaut由OCI开发,基于注解的依赖注入,内置多种特性,轻量级且启动迅速;Spring Boot则简化了Spring应用开发,拥有丰富的生态支持。选择框架需考虑项目需求、团队经验、性能要求及社区支持等因素。希望本文能帮助您选择合适的微服务框架,助力您的软件开发项目取得成功!
158 2
|
2月前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
34 3
|
7天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
23 6
|
27天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
34 10