zeroc-ice的全双工通信策略

简介: 在项目中,往往很多时候涉及全双工通信要求,zeroc-ice样例介绍很多异步通信的策略, 但我最近项目需求中,不仅是要全双工通信,还要求服务端需要明确每个客户端及区别对待, 所以需要给每个客户端做标记处理...

在项目中,往往很多时候涉及全双工通信要求,zeroc-ice样例介绍很多异步通信的策略,

但我最近项目需求中,不仅是要全双工通信,还要求服务端需要明确每个客户端及区别对待,

所以需要给每个客户端做标记处理

1)ice定义

#pragma once
#include <Ice/Identity.ice>

module TestIce
{

struct DateTimeI {
    int    isec;
    int imsec;
};

interface ClientAchieve
{

   //客户端实现

    void PValueChange_A(long devID,long pID, DateTimeI itime, float val);//A类客户端实现

    void PValueChange_B(long devID,long pID, DateTimeI itime, float val);//B类客户端实现

};

interface ServerAchieve
{

    //服务端实现

    void AddClient(::Ice::Identity ident, int ctype);
    void setPValue(long devID, long pID, float val);
};

};

2)接口实现:

在我的ice定义中

void AddClient(::Ice::Identity ident, int ctype);是很关键的一项,该函数是有服务端实现,

在客户端链接成功将其识别号及类型告知服务端,服务端将进行标记,该逻辑过程如下:

客户端链接及通告服务端代码样例

                Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("");
                Ice::Identity ident;
                ident.name = IceUtil::generateUUID();
                m_strUUID = ident.name;
                ident.category = "";
                ClientAchievePtr crtwoway = new ClientAchieveI(this);
                adapter->add(crtwoway, ident);
                adapter->activate();
                soneway->ice_getConnection()->setAdapter(adapter);
                soneway->AddClient(ident,ctype);//通知服务端

而在服务端,我们将进行标记每个客户端,示例代码:

void ServerAchieveI::AddClient(const ::Ice::Identity& ident,const ::Ice::Int &ctype, const ::Ice::Current& current)
{
      printf("adding client `%s(%d)'\n", _communicator->identityToString(ident).c_str(),ctype);
     TestIce::ClientAchievePrx client = PCS::ClientAchievePrx::uncheckedCast(current.con->createProxy(ident));

    //clients定义了一个客户端管理类,采用std::map<TestIce::ClientAchievePrx, ClientFlag> _clients;进行客户端标记

     clients->addCLient(client,ctype);
};


现在我们展示服务端接口代码示例:

class ClientManageThread;

class ServerAchieveI : public TestIce::ServerAchieve
{
public:
    ServerAchieveI(const Ice::CommunicatorPtr& communicator);
    virtual ~ServerAchieveI();
    //
    virtual void AddClient(const ::Ice::Identity&, const ::Ice::Int &ctype,const ::Ice::Current& = ::Ice::Current());
    virtual void setPValue(::Ice::Long devID, ::Ice::Long pID, float val, const ::Ice::Current&);
private:
    // Required to prevent compiler warnings with MSVC++
    ServerAchieveI& operator=(const ServerAchieveI&);

    Ice::CommunicatorPtr _communicator;
    ClientManageThread *clients;
};

/////////////////////////////////////
ServerAchieveI::ServerAchieveI(const Ice::CommunicatorPtr& communicator)
    : _communicator(communicator)
{
    clients = new ClientManageThread();
    clients->start();
};

ServerAchieveI::~ServerAchieveI()
{
    try
    {
        delete clients;
        clients = NULL;
    }
    catch (...)
    {
        
    }
};

void ServerAchieveI::AddClient(const ::Ice::Identity& ident, const ::Ice::Int &ctype,const ::Ice::Current& current)
{
      printf("adding client `%s(%d)'\n", _communicator->identityToString(ident).c_str(),ctype);
    TestIce::ClientAchievePrx client = TestIce::ClientAchievePrx::uncheckedCast(current.con->createProxy(ident));
    clients->addCLient(client,ctype);//clients根据ctype类型调用TestIce::ClientAchievePrx的客户端实现函数发送数据到指定客户端
};
//客户端调用该函数实现客户端到服务端的数据发送,soneway->setPValue(devID,pID,val);
void ServerAchieveI::setPValue(::Ice::Long devID, ::Ice::Long pID, float val, const ::Ice::Current& )
{
    std::cerr << " setPValue:"<< devID<<","<<pID<<","<<val << std::endl;
    PFrom _pfrom;
};

展示客户端代码样例,例如该客户端只需实现A类型函数:

///////////////////////////////h////////////////////////////////////////////////////////////////

class TestIceClient;

class ClientAchieveI : public TestIce::ClientAchieve
{
public:
    ClientAchieveI(TestIceClient* _client);
    ~ClientAchieveI();
    virtual void PValueChange_A(::Ice::Long devID
                              ,::Ice::Long pID
                              , const ::TestIce::DateTimeI& itime
                              , ::Ice::Float val
                              , const ::Ice::Current&);
private:
    TestIceClient* client;//真正实现类
};

/////////////////////////////////////////////cpp/////////////////////////////////////

ClientAchieveI::ClientAchieveI(TestIceClient* _client) : client(_client)
{
};

ClientAchieveI::~ClientAchieveI()
{

};

void ClientAchieveI::PValueChange(::Ice::Long devID
                              ,::Ice::Long pID
                              , const ::TestIce::DateTimeI& itime
                              , ::Ice::Float val
                              , const ::Ice::Current&)
{

    std::cerr <<" PValueChange:" <<devID<<","<<pID<<","<<val<<","<<itime.isec<<","<<itime.imsec<< std::endl;

    if(client)
        client->PValueChange(devID,pID,itime,val);
};

3)实现调用示例:

在我的ClientManageThread类中,实现数据从服务端发送各客户端:

            mutex_client.Lock();
            std::map<TestIce::ClientAchievePrx, int>::iterator itw = _clients.begin();
            while(itw != _clients.end())
            {
                try
                {

                   switch(it->second)
                    {
                        case 1:
                            itw->first->PValueChange_A(wdlc.devID, wdlc.pID, _itime, wdlc.val);
                        break;
                        case 2:
                            itw->first->PValueChange_B(wdlc.devID, wdlc.pID, _itime, wdlc.val);
                        break;
                        default:
                        break;
                    }
                    itw++;
                }
                catch (...)
                {
                    printf("PValueChange Error:%d\n",static_cast<int>(time(NULL)));
#ifdef WIN32
                    itw = _clients.erase(itw);
#else
                    std::map<TestIce::ClientAchievePrx, int>::iterator ittmp = itw++;
                    _clients.erase(ittmp);
#endif
                }
            }
            mutex_client.Unlock();

在客户端调用与已很多zeroc-ice的demoo一致:

//TestIce::ServerAchievePrx            soneway;

    if(connect())
    {
        try{            soneway->setPValue(devID,pID,val);
        }catch(...)
        {
            disconnect();
        }
    }


本文只是抛出一个zeroc-ice做全双工通信的思路,所展示代码只是具体代码中择取的代码,功能并不完善,大家可按自身需求修改完善适合自身项目诉求

目录
相关文章
数据通信方式
数据通信方式。
209 2
|
1月前
|
传感器 安全 Java
如何使用 CoAP 协议进行设备通信
CoAP(Constrained Application Protocol)是一种适用于资源受限设备的轻量级协议,常用于物联网(IoT)设备之间的通信。本文介绍如何使用 CoAP 协议进行设备通信,包括协议的基本概念、消息格式、请求与响应流程以及实际应用示例。
|
5月前
|
供应链 自动驾驶 物联网
5G通信
7月更文挑战第2天
|
6月前
|
网络协议 API 开发者
无线通信模块通过TCP/IP协议实现与PC端的数据传输
本文介绍了无线通信模块借助TCP/IP协议向PC端传输数据的过程,包括数据封装、发送和接收,并以WIFI模块为例,讨论了在QT平台下实现无线数据传输的方法。通过QTcpSocket类,开发者能轻松建立WIFI模块与PC间的连接。随着无线通信技术的进步,未来将有更多创新应用出现。
|
设计模式 缓存 网络协议
网络协议 | 典型协议、B/S模式、C/S模式
网络协议 | 典型协议、B/S模式、C/S模式
332 0
|
网络协议
通信模型与通信中的问题
通信模型 通信 信源 信源编码 信道 信宿 信源编码
209 0
通信模型与通信中的问题
|
网络协议 开发者 数据格式
WebSocket:实时通信的全双工解决方案
WebSocket是一种基于TCP的实时通信协议,它在Web应用中提供了全双工、持久化的连接,使得服务器和客户端之间可以实时地进行双向通信。本文将介绍WebSocket的特点和优势,探讨它在Web应用中的广泛应用场景。我们还将深入了解WebSocket的工作原理和使用方法,帮助开发者了解如何利用WebSocket构建高效、实时的Web应用。
365 0
EMQ
|
网络协议 中间件 物联网
QUIC 多流桥接、新增 DDS 协议转换代理
即将发布的超轻量 MQTT Broker NanoMQ 0.16为用户提供了2个重要新功能:MQTT over QUIC的多流桥接和DDS协议转换代理,拓宽了其弱网桥接传输性能和在边缘端的使用场景。
EMQ
349 0
QUIC 多流桥接、新增 DDS 协议转换代理
|
数据格式 流计算
【UCIe】UCIe 支持的协议及操作模式
【UCIe】UCIe 支持的协议及操作模式
2102 1
【UCIe】UCIe 支持的协议及操作模式
|
网络协议 网络虚拟化 芯片
AUTOSAR以太网通信架构概述
AUTOSAR以太网通信架构概述
AUTOSAR以太网通信架构概述