VC实现远程对象方法调用及事件订阅触发,方便开发C/S系统参考flash远程共享对象,方便客户端调用远程功能,可同时包含多个应用,一个应用下包含多个远程对象,远程应用对象的目录结构如下图网络通讯部分采用完成端口模式,通讯数据采用封装数据对象XVarArray,该对象支持基本数据类型intint64by
VC实现远程对象方法调用及事件订阅触发,方便开发C/S系统

参考flash远程共享对象,方便客户端调用远程功能,可同时包含多个应用,一个应用下包含多个远程对象,远程应用对象的目录结构如下图

网络通讯部分采用完成端口模式,通讯数据采用封装数据对象XVarArray,该对象支持基本数据类型int int64 bytes long float char *,该对象常用函数如下:
static bool AttachBytes(BYTE *pByte,int nLength,OutManyVarArray &m_OutManyVarArray);
void Copy(XVarArray &m_XVarArray);
bool RemoveElementAt(int nIndex);
int GetElementCount();
bool ReadElement(void *pElement,BYTE &nType,int &L);
bool SetOrderElementPos(int nNum);//设置到第几个元素
bool ReadObj(void *pObj,int &L);
bool ReadBytes(BYTE *pByte,int &L);
bool ReadStr(char *pStr,int &L);
bool ReadInt64(__int64 &iZhi64);
bool ReadFloat(float &fZhi);
bool ReadInt(int &iZhi);
void SetRealPos(int nPostion);
void SetRealPosEnd();
void SetRealPosBegin();
void WriteObj(void *pObj,int L);
void WriteBytes(unsigned char *pByte,int L);
void WriteStr(char *pStr);
void WriteInt64(__int64 iZhi64);
void WriteFloat(float fZhi);
void WriteInt(int nZhi);
XVarArray & operator =(XVarArray &Var);
封装的远程对象基类,方便编写远程对象
#include "..\include\XNetEvent.h"
typedef map<string,XNetEvent *>XNetEventType;//对象的所有事件
class AFX_EXT_CLASS XOneObject
{
public:
void GetEvents(CStringArray &m_EventArray);
void DebugObj(char *pStr);
void *pXOneApp;
bool bDIYEvent;//自定义触发事件
void InitPack();
virtual void RemoveSOCKET(SOCKET s);//一个SOCKET 掉线
void RemoveSEvent(SOCKET s);
HANDLE hNet;
DWORD pBasePack;//公有对象使用同一个,私有对象拥有独立连接的
void AddOneEvent(char *sEventName);
void PostEvent(char *sEventName,XVarArray &m_XVarArray);
bool bPublic;
CString sAppName;
CString sObjName;
CStringArray m_EventNameArray;
virtual void InitObjEvent();
bool CallClientFunc(char *sFName,XVarArray &InVarArray,XVarArray &OutVarArray);
bool GetAllFuncNameArray(CStringArray &NameArray);
typedef bool (XOneObject::*pCLASSFUNC)(SOCKET s,XVarArray &InVarArray, XVarArray &OutVarArray,bool &bClose,DWORD &dwObject,int nThreadNO);
typedef map<string,pCLASSFUNC>XCLASSFUNC;
XOneObject();
virtual ~XOneObject();
virtual void InitObject();
virtual XOneObject * GetAnOtherObject();
int nTestZhi;
bool ExampFunc(SOCKET s,XVarArray &InVarArray, XVarArray &OutVarArray,bool &bClose,DWORD &dwObject,int nThreadNO);
void PushFuncName(char *sFName,pCLASSFUNC pFunc);
bool CallFunc(char *sFName,SOCKET s,XVarArray &InVarArray,XVarArray &OutVarArray,bool &bClose,DWORD &dwObject,int nThreadNO);
bool AttachOneEvent(char *sEventName,SOCKET s,char *sUserID);
protected:
XCLASSFUNC m_XCLASSFUNC;
XNetEventType m_XNetEventType;
};
派生该基类实现远程对象如:
class XShareObjectNO2:public XOneObject
{
public:
//典型的对象函数 参数s:网络连接SOCKET ,InVarArray:输入参数:OutVarArray:输出参数,bClose:返会true表示断开连接,nThreadNO:表示在服务端低几个线程调用
bool JsonFunction(SOCKET s,XVarArray &InVarArray, XVarArray &OutVarArray,bool &bClose,DWORD &dwObject,int nThreadNO);
void InitObjEvent();//初始化对象事件
bool AddStr(SOCKET s,XVarArray &InVarArray, XVarArray &OutVarArray,bool &bClose,DWORD &dwObject,int nThreadNO);
XOneObject * GetAnOtherObject();
bool MyFunc(SOCKET s,XVarArray &InVarArray, XVarArray &OutVarArray,bool &bClose,DWORD &dwObject,int nThreadNO);
void InitObject();//初始化对象基本参数
XShareObjectNO2();
virtual ~XShareObjectNO2();
};
实现类:
XShareObjectNO2::XShareObjectNO2()
{
}
XShareObjectNO2::~XShareObjectNO2()
{
}
void XShareObjectNO2::InitObject()
{MyFunc
PushFuncName("MyFunc",static_cast<XOneObject::pCLASSFUNC>(&XShareObjectNO2::MyFunc));//初始对象函数MyFunc指向函数MyFunc
PushFuncName("AddStr",static_cast<XOneObject::pCLASSFUNC>(&XShareObjectNO2::AddStr));//初始对象函数AddStr指向函数AddStr
PushFuncName("JsonFunction",static_cast<XOneObject::pCLASSFUNC>(&XShareObjectNO2::JsonFunction));//初始对象函数AddStr指向函数JsonFunction
}
bool XShareObjectNO2::MyFunc(SOCKET s,XVarArray &InVarArray, XVarArray &OutVarArray,bool &bClose,DWORD &dwObject,int nThreadNO)
{
bClose=false;
InVarArray.SetRealPosBegin();
int a,b;
InVarArray.ReadInt(a);
InVarArray.ReadInt(b);
int c=a*b;
OutVarArray.WriteInt(c);
OutVarArray.SetRealPosBegin();
return true;
}
XOneObject * XShareObjectNO2::GetAnOtherObject()
{
XShareObjectNO2 *pShareObjectNO2=new XShareObjectNO2();
pShareObjectNO2->InitObject();
pShareObjectNO2->InitObjEvent();
pShareObjectNO2->hNet=hNet;
return pShareObjectNO2;
}
bool XShareObjectNO2::AddStr(SOCKET s,XVarArray &InVarArray, XVarArray &OutVarArray,bool &bClose,DWORD &dwObject,int nThreadNO)
{
bClose=false;
InVarArray.SetRealPosBegin();
char Str1[200],Str2[200];
int L;
InVarArray.ReadStr(NULL,L);
char *pStr1=new char [L+1];
InVarArray.ReadStr(pStr1,L);
pStr1[L]=0;
InVarArray.ReadStr(NULL,L);
char *pStr2=new char [L+1];
InVarArray.ReadStr(pStr2,L);
pStr2[L]=0;
CString TStr;
TStr.Format("%s%s",pStr1,pStr2);
delete[]pStr1;
delete[]pStr2;
OutVarArray.WriteStr((char *)(const char *)TStr);
OutVarArray.SetRealPosBegin();
XVarArray m_XVarArray0;
m_XVarArray0.WriteStr("DataChange 事件触发的消息");
PostEvent("DataChange",m_XVarArray0);//触发DataChange事件
return true;
}
void XShareObjectNO2::InitObjEvent()
{
AddOneEvent("DataChange");//初始化对象事件DataChange
AddOneEvent("JsonEvent");//初始化对象事件JsonEvent
}
bool XShareObjectNO2::JsonFunction(SOCKET s, XVarArray &InVarArray, XVarArray &OutVarArray, bool &bClose, DWORD &dwObject, int nThreadNO)
{
bClose=false;
InVarArray.SetRealPosBegin();
int L;
InVarArray.ReadStr(NULL,L);
char *pStr=new char[L+1];
memset(pStr,0,L+1);
InVarArray.ReadStr(pStr,L);
OutVarArray.WriteStr(pStr);
PostEvent("JsonEvent",OutVarArray);
delete[]pStr;
return true;
}
对象dll装载公有输出函数如:
extern DWORD WINAPI GetOneObject(char *sObjectName)//获得指定名称的远程对象
{
if(strcmp(sObjectName,"XShareObjectNO1")==0)
{
XShareObjectNO1 *pShareObjectNO1=new XShareObjectNO1();
pShareObjectNO1->InitObject();
pShareObjectNO1->InitObjEvent();
return (DWORD)pShareObjectNO1;
}
else
{
if(strcmp(sObjectName,"XShareObjectNO2")==0)
{
XShareObjectNO2 *pShareObjectNO2=new XShareObjectNO2();
pShareObjectNO2->InitObject();
pShareObjectNO2->InitObjEvent();
return (DWORD)pShareObjectNO2;
}
}
}
extern bool WINAPI GetModeObjectsName(CStringArray &ObjectNameArray)//获得当前dll中包含哪些远程对象名
{
ObjectNameArray.RemoveAll();
ObjectNameArray.Add("XShareObjectNO1");
ObjectNameArray.Add("XShareObjectNO2");
return true;
}
extern bool WINAPI GetOneObjectAllFuncName(DWORD pXOneObject,CStringArray &ObjectFunNameArray) //返回对象包含的函数名
{
XOneObject *pXOneObject0=(XOneObject *)pXOneObject;
pXOneObject0->GetAllFuncNameArray(ObjectFunNameArray);
return true;
}
为方便客户端调用,封装客户端调用框架,目前支持的VC C# Java的客户端调用
以VC客户端为例
class AFX_EXT_CLASS XClientNetCtrl
{
public:
void CloseOneNet(char *sAppName);//关闭一个远程应用
bool CallShareObjectFunc(XClientShareObject *pXClientShareObject,char *sFName,XVarArray &m_VarArray,XVarArray *pOutXVarArray=NULL);//调用远程对象方法
XClientShareObject * GetOneNetShareObject(char *sAppName,char *sShareObjectName,bool bPerson=false);//获得一个远程对象 sAppName:应用名 sShareObjectName:对象名
bool GetOneAppNet(char *sIP,UINT nPort,char *sAppName,pRUNCLASSFUNC pExitNet=NULL,DWORD pXRunShareObjectBase=0);//获得一个应用
XClientOneNetArray m_XClientOneNetArray;
XClientOneNetFromNameArray m_XClientOneNetFromNameArray;
XClientNetCtrl();
virtual ~XClientNetCtrl();
};
class AFX_EXT_CLASS XClientShareObject //客户端对象的基类
{
public:
bool EventOutFunc(char *sEventName,XVarArray &OutVarArray);
void AppAdd(HANDLE hNet,char *sPAppName,DWORD pXClientOneNet);
bool OutFuncResult(char *sFName,XVarArray &m_XVarArray);
void AttachXNetFuncReult(char *sFName,DWORD pXRunShareObjectBase,pRUNCLASSFUNC pFunc);
bool ActOneFunc(char *sFName,XVarArray &m_InXVarArray,XVarArray *pOutXVarArray=NULL);//执行运行函数,如果要等待结果那么就要赋pOutXVarArray,如果不用等待只是用结果事件那么不用赋值;
char sName[150];
bool RunOutFunc(char *sEventName);
typedef map<string ,struct RunBaseST *>XRUNCLASSFUNCBASE;
XRUNCLASSFUNCBASE m_XEVENTCLASSFUNCBASE;
XRUNCLASSFUNCBASE m_XFUNCOUTFUNCBASE;
void AttachXNetEvent(char *sEventName,DWORD pXRunShareObjectBase,pRUNCLASSFUNC pFunc);
void AddListenEvent(char *sEventName);
void SetNetEventFunc(NetEvent *pNetEvent0);
NetEvent *pNetEvent;
CStringArray m_ListenNameArray;
void *pParentApp;
bool bPerson;
XClientShareObject();
virtual ~XClientShareObject();
};
客户端调用的例子
class CNetRunDlg : public CDialog, XRunShareObjectBase
{
// Construction
public:
void OBEventResult(XClientShareObject *pXClientShareObject, char *sEventName, XVarArray &OutXVarArray, DWORD pThis);
void OBFuncResult(XClientShareObject *pXClientShareObject, char *sEventName, XVarArray &OutXVarArray, DWORD pThis);
void OnNetExitEvent(XClientShareObject *pXClientShareObject, char *sEventName, XVarArray &OutXVarArray, DWORD pThis);
CNetRunDlg(CWnd* pParent = NULL); // standard constructor
XClientShareObject *pXShareObject1,*pXShareObject2;
XClientNetCtrl m_XClientNetCtrl;
// Dialog Data
//{{AFX_DATA(CNetRunDlg)
enum { IDD = IDD_NETRUN_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CNetRunDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CNetRunDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButton1();
afx_msg void OnButton2();
afx_msg void OnButton4();
afx_msg void OnButton3();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
初始
m_XClientNetCtrl.GetOneAppNet("192.168.0.1",5242,"game",static_cast<pRUNCLASSFUNC>(&CNetRunDlg::OnNetExitEvent),(DWORD)this);//连接服务器
pXShareObject1=m_XClientNetCtrl.GetOneNetShareObject("game","XShareObjectNO1",true);//获得远程对象XShareObjectNO1
pXShareObject1->AttachXNetFuncReult("NO2Func",(DWORD)this,static_cast<pRUNCLASSFUNC>(&CNetRunDlg::OBFuncResult));//绑定远程序对象XShareObjectNO1函数NO2Func返回函数
pXShareObject1->AttachXNetEvent("DataChange",(DWORD)this,static_cast<pRUNCLASSFUNC>(&CNetRunDlg::OBEventResult));//绑定远程序对象XShareObjectNO1事件函数DataChange
pXShareObject2=m_XClientNetCtrl.GetOneNetShareObject("game","XShareObjectNO2",true);//获得远程对象XShareObjectNO2
pXShareObject2->AttachXNetFuncReult("AddStr",(DWORD)this,static_cast<pRUNCLASSFUNC>(&CNetRunDlg::OBFuncResult));//绑定远程序对象XShareObjectNO2函数NO2Func返回函数
pXShareObject2->AttachXNetEvent("DataChange",(DWORD)this,static_cast<pRUNCLASSFUNC>(&CNetRunDlg::OBEventResult));//绑定远程序对象XShareObjectNO2事件函数DataChange
void CNetRunDlg::OnNetExitEvent(XClientShareObject *pXClientShareObject, char *sEventName, XVarArray &OutXVarArray, DWORD pThis)
{
CNetRunDlg *pNetRunDlg=(CNetRunDlg *)pThis;
}
void CNetRunDlg::OBFuncResult(XClientShareObject *pXClientShareObject, char *sFuncName, XVarArray &OutXVarArray, DWORD pThis)//*sFuncName:执行的函数,OutXVarArray返回的结果
{
CNetRunDlg *pNetRunDlg=(CNetRunDlg *)pThis;
}
void CNetRunDlg::OBEventResult(XClientShareObject *pXClientShareObject, char *sEventName, XVarArray &OutXVarArray, DWORD pThis)//*sEventName:返回的事件,OutXVarArray返回的结果
{
CNetRunDlg *pNetRunDlg=(CNetRunDlg *)pThis;
char TStr[100];
int L;
OutXVarArray.ReadStr(TStr,L);
TStr[L]=0;
AfxMessageBox(TStr);
}
XShareObjectNO2调用函数
XVarArray m_XVarArray,m_XOutVarArray;
m_XVarArray.WriteStr("中国");
m_XVarArray.WriteStr("北京");
pXShareObject2->ActOneFunc("AddStr",m_XVarArray,&m_XOutVarArray);
char TStr[200];
int L;
m_XOutVarArray.ReadStr(TStr,L);
TStr[L]=0;
AfxMessageBox(TStr);
TRACE("ok");
基于该远程对象实现一个类QQ的聊天工具PCEQ,实现点对点聊天,群聊,文件传输,远程协助,语音聊天,视频聊天等常用功能

如今消息生产消费订阅已经有不少成熟的开发包可调用,而那些年你也是否自己造了一大堆轮子呢?
赠送20本心理学电子书,添加 微信:56163509 备注:心理学!
如若转载,请注明出处:https://www.xinli1988.com/450.html