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

2025-05-03 16:40:09

需求:

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

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

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

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

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

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

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

线程安全的队列:

代码语言:javascript代码运行次数:0运行复制//AsyncExecQueue.h

#pragma once

#include

#include

#include

#include

#include

#include

#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> que;

AsyncExecQueue() {

this->maxsz = 0;

}

public:

//实现单例模式

static AsyncExecQueue* Instance() {

static AsyncExecQueue obj;

return &obj;

}

//任务对象出队

bool pop(shared_ptr& item);

//任务对象入队

bool push(shared_ptr item);

};

//AsyncExecQueue.cpp

#include "AsyncExecQueue.h"

//任务对象出队

bool AsyncExecQueue::pop(shared_ptr& item) {

lock_guard lk(mutx);

if (que.empty()) return false;

item = que.front(); que.pop();

return true;

}

//任务对象入队

bool AsyncExecQueue::push(shared_ptr item)

{

std::lock_guard lk(mutx);

if (maxsz > 0 && que.size() >= maxsz) return false;

que.push(item);

return true;

}