一个比较典型的Web端如何集成C/S端程序的思路


需求:

一个三方的广播、对讲系统,需要集成到已有的平台,已有平台采用的是B/S架构,也就是用户通过Web端来实现管理需求;

三方的广播、对讲系统则是一个C/S架构的程序,提供三方可以定制开发的Windows端的SDK,这就有了这个积木式程序的开发!

 

框架图如下:最终是实现一个windows端的本地服务,安装在用户的PC电脑上,web端调度员使用web就能实现相同的C/S端程序的能力!


呱牛笔记

web端集成mqtt的客户端,接入MQTT服务器,然后通过推送给windows本地服务下发控制指令,比方开始广播、停止广播等指令!


windows本地服务接收到推送指令后,调用相应的功能模块提供的API,完成本地的功能调用,并将结果通过推送通知到web端!


mqtt推送指令中使用json作为消息体,传递控制和回应消息,请求格式和相应格式如下图:

呱牛笔记


麻雀虽小五脏俱全,集成了glog,方便后续问题定位和分析!


线程安全的队列:

//AsyncExecQueue.h
#pragma once

#include <stdio.h>
#include <string>
#include <iostream>
#include <atomic>
#include <mutex>
#include <queue>

#include "logutils.h"
using namespace std;

class MessageItem {

public:
  MessageItem() {
    m_topic = NULL;
    m_content = NULL;
  }
  MessageItem(string &topic, string &content) {
    m_topic = (char *)malloc(topic.length() + 1);
    if (m_topic == NULL) {
      LOGD("m_topic == NULL");
      return;
    }
    memset(m_topic, 0x00, topic.length() + 1);
    memcpy(m_topic, topic.c_str(), topic.length());
    m_topic[topic.size()] = '\0';

    m_content = (char*)malloc(content.size() + 1);
    if (m_content == NULL) {
      LOGD("m_topic == NULL");
      return;
    }
    memset(m_content, 0x00, content.size() + 1);
    memcpy(m_content, content.c_str(), content.size());
    m_content[content.size()] = '\0';
    LOGD("addr:%0x value:%s, size:%d, content:%0x, value:%s size:%d", m_topic, m_topic, topic.length(), m_content, m_content, content.size());
  }
  ~MessageItem() {
    if (m_topic) { free(m_topic);
    m_topic = NULL;
    }
    if (m_content) {
      free(m_content);
      m_content = NULL;
    } 
  }

  char *m_topic;
  char *m_content;
};

//自旋锁类
class SpinMutex
{
private:
  atomic_flag flag = ATOMIC_FLAG_INIT;

public:
  void lock()
  {
    while (flag.test_and_set(memory_order_acquire));
  }
  void unlock()
  {
    flag.clear(std::memory_order_release);
  }
};

class AsyncExecQueue
{
private:
  size_t maxsz; 
  mutable SpinMutex mutx;
  queue<shared_ptr<MessageItem>> que;

  AsyncExecQueue()  {
    this->maxsz = 0;
  } 
public:
  //实现单例模式
  static AsyncExecQueue* Instance() {
    static AsyncExecQueue obj;
    return &obj;
  }
   
  //任务对象出队
  bool pop(shared_ptr<MessageItem>& item);

  //任务对象入队
  bool push(shared_ptr<MessageItem> item);

};


//AsyncExecQueue.cpp
#include "AsyncExecQueue.h"


//任务对象出队
bool AsyncExecQueue::pop(shared_ptr<MessageItem>& item) {
  lock_guard<SpinMutex> lk(mutx);
  if (que.empty()) return false;
  item = que.front(); que.pop();
  return true;
}

//任务对象入队
bool AsyncExecQueue::push(shared_ptr<MessageItem> item)
{
  std::lock_guard<SpinMutex> lk(mutx);
  if (maxsz > 0 && que.size() >= maxsz) return false;
  que.push(item);
  return true;
}


本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com

请先登录后发表评论
  • 最新评论
  • 总共0条评论