求救~~~~!!COM+ 对象池实现的问题~~!!

it_manager 2006-05-03 06:30:04
研究摸索了一个星期了,对象池这个东西仍然没有搞定,非常的苦恼,唉~~,所以特来此发帖,恳请有经验的朋友指点和帮助.

我要做的是一个网络连接的对象池,前端应用在IIS中运行,要通过调用这个连接池对象来获得状态,参数和执行指令,所以没有办法,就只能通过COM+的这个所谓容器来实现我要达到的效果了.

看了网络上大量的资料,我也做出来了一个COM组件,也按照资料上讲的,都实现了IObjectControl接口,在组件服务中添加也正常,但发生一个怪现象, 如果我在组件服务中选择"启用对象池"并设置5个~100个连接后,前端应用在调用就会出现"自动化错误"的提示, 但如果我取消"启用对象池",前端的应用代码反而可以成功,但就是没有对象池的效果.

网上查了许多资料,似乎都没有一个完整的COM+对象池的代码例子可以参考,现在自己摸索着做,真的很难,感觉无助啊~~~~~~~~~~~~~~~~!!! 求求大家帮帮我吧,我快要崩溃了.


恳请大家帮忙,指点,兄弟感激不尽!!!!!!!

如果能有这样的COM+对象池代码就最好不过了.
...全文
320 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
it_manager 2006-07-12
  • 打赏
  • 举报
回复
horris:

再次感谢您的指导,从您的回复中我找到了具体的问题,是因为我所采用的openssl底层代码中调用的临界段函数在win2003上工作不正常导致的,我采用事件的方式替代解决了这一问题。

呵呵,现在我做的部分已经通过不同平台(XP,WIN2000,WIN2003,2000 SERVER等)的压力测试,效果还不错,感慨颇多,系统运行的效果还是蛮不错的。另外我还根据您前面提到的组件服务COM组件实现了对组件应用添加删除以及所有的操作,全部可以通过程序来控制和实现。

感叹CSDN这个平台,也很佩服和感谢horris这样的高手,说大点讲得上是义举了,说真的,当初的迷茫和苦恼能通过CSDN,得到horris的帮助而化解,心情很复杂,哈哈。。。

向horris致敬! 感谢帮助!

BTW,以后其他人有任何需要COM+对象池类似的技术问题帮助,也可以发消息给我。学不到horris那样高的水平,这个精神和行为我还是可以学到的。呵呵

horris 2006-06-24
  • 打赏
  • 举报
回复
应该是程序中实现永久保持连接的部分有BUG,可能你在Win2000上并没有仔细作测试。
it_manager 2006-06-22
  • 打赏
  • 举报
回复
horris,你好,感谢您的回复.

用COM+总算实现了对象池,并且也经过了一般性的压力测试,但在win2003上进行部署变得不稳定,感觉是心力焦瘁了.

win2000上通过了完整的压力测试,一切运行正常,我在此COM+对象中通过定时器实现了永久保持连接,并且加上了非常多的容错功能, 但在win2003上问题变得麻烦了,安装后重新启动后,COM+对象都能正常被调用,池化,但一旦关闭COM+对象或者组件中的异常错误,就再也无法启动,除非重新启动计算机.感觉真是无法摸透微软平台的东西,2000上非常稳定,但同样的东西在2003上就变得不可控了,而且系统日志中也没有任何错误信息.

望能得到您的指点,这恐怕是我仅存的一线希望了,多谢!!!!!!!!
horris 2006-05-31
  • 打赏
  • 举报
回复
对于池装组件将自身从池中删除,我不了解有什么方法,你可以看看COMAdmin库,这是一套管理COM+应用的API,操作系统的交互式管理工具“组件服务”中有的功能它都可以实现,而且还能做后者不能做的工作。
你还可以试试整新回收整个COM+应用的进程。
对于轮询,我想这就需要你在服务器端做一个服务或任务计划。还有一个方案,就是在组件自身产生一个线程,这个线程做轮询的工作。这样做的话,建议你最好把COM+应用设置为“空闲时保持运行”(通过属性的“高级”夹)。
it_manager 2006-05-31
  • 打赏
  • 举报
回复
谢谢楼上horris的回复,出差才回来,抱歉到现在还没有结帖,非常感谢2位的热情帮助.

现在采纳了horris的建议进行改进和处理后,速度确实快了,基本上能满足我的应用了,但又遇到了新的问题,还望2位再次指点,给些建议,非常感谢:

因为我做的这个对象池主要任务是建立SSL的网络连接,对象池实现后,对象被回收后,其连接并没有断开,但服务器端会因为连接长时间没有活动而自动断开,所以我就在想,是否可以在COM组件中做一个轮询的服务,隔一段时间自动在空闲的时候去发送一个NOOP指令,以维护这样一个网络连接,不知道这样是否可以实现?

还有就是,如果轮询服务发现当前连接已经不再可用,或者遇到不可恢复的故障时,是否可以自己将自身彻底从池中删除掉? 而不是重新放回池中?

恳请2位解答,多谢!!!
horris 2006-05-11
  • 打赏
  • 举报
回复
我提的1,是我的实践经验,而且有MSDN为证,必须这么做,除非你在COM+中定义了方法级强制JIT。
至于4,如果设为Both的话,那么当STA客户端调用你的组件时,组件将在一个对应于该客户端的STA中创建,这样其他客户端在使用这个组件实例时,就会发生线程切换以及调用阻塞,极大影响性能,失去了池装对象的意义。
对于你的IIS情形,应该不会有那么大的性能损失,你实行我提的1和4再试试。
it_manager 2006-05-09
  • 打赏
  • 举报
回复
感谢horris的回复, 下载了Pipi0714(老顽童) 给的代码后,问题基本上解决了.

我原来没接触过com+,确实因为应用需要,才开始弄,时间紧张,具体细节也没多看,见笑了.但对于horris提到的第1点,所有组件类方法,属性返回前都必须调用setcomplete(),这个我有些不大明白,我现在的com+组件似乎没这么处理,经过测试,也能有池化的效果? 至于2,3点,这些我倒是注意到了. 至于第4点,我采取的是both方式,这个从资料上的说明来看,好像也是种不错的选择?


另外还有个问题,恳请 horris 和 老顽童 关注一下,再次感谢:

不知两位是否有做过IIS的应用? 我现在要在IIS中实现一个全局的公共对象,似乎IIS除了采取COM+组件容器,没有别的办法了? 但COM+通过今天的测试,发现效果并不理想,因为这样大大降低了我前端应用的效率.

不知道结合IIS有没有类似tomcat或者weblogic一样的应用容器? 或者我可以自己定义代码写一个ASP的运行容器? 只要达到全局共享一个公共对象就可以了(访问互斥和同步这个对象来处理).

开始也试过用IIS中内置的APPLICATION来存储对象,正如微软所提到的,这样不是个好办法,最终会造成串行效果,我通过测试工具在模拟100个用户同时访问的情况下,所有的处理都阻塞在Application的对象获取上了,所以后来没法,就考虑采取COM+.



非常感谢2位高手的热情帮助,感激不尽,如有机会,很想认识2位(记得我原来提过几次问题,2位也有过解答), 我的QQ号: 40297952 ,如果方便,麻烦加一下我.
horris 2006-05-09
  • 打赏
  • 举报
回复
你没有好好看文档,仅从贴上来的代码看,有很多基础知识都不懂。
1。组件类的所有方法、属性在返回前,都应调用IObjectContext::SetComplete :
m_spObjectContext->SetComplete(...)
不这么做,JIT就不起作用,你的组件实例就不会被去激活,也就不会被放回池中供其实客户端使用。
2。要记住,组件类的所有数据成员都可能被其它客户端使用,所以数据成员不要存储特定于某个客户端的信息。
3。组件类的所有数据成员都要有同步保护,因为可池装对象有可能被多个线程同时访问,也就是说,可能有多个线程同时读、写一个组件实例的同一个数据成员。
4。建议把.rgs文件中的ThreadModel改为Free或Neutral。
it_manager 2006-05-08
  • 打赏
  • 举报
回复
嗯.多谢多谢,真的感谢,我先看看
it_manager 2006-05-08
  • 打赏
  • 举报
回复
谢谢Pipi0714 老顽童,

codeproject我找过了,并没有发现有com+的例子,并且对于com+对象池的例子所有开源站点都非常少, codeproject有个关于com+连接池的文章我倒是看过了,但没什么用,都是概念性的叙述,没有实际的代码...
Pipi0714 2006-05-08
  • 打赏
  • 举报
回复
看看这个网址的有例子代码:搞底层的东西需要的知识越多


http://comcamp.diy.myrice.com/techarticles/com/2011.htm
it_manager 2006-05-08
  • 打赏
  • 举报
回复
前面的代码贴错了,贴成不支持pool模式的代码了,代码如下:

//==================================================
//头文件部分:
//==================================================

class ATL_NO_VTABLE CSSLNet :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CSSLNet, &CLSID_SSLNet>,
public IObjectControl, //// POOL ////
public IDispatchImpl<ISSLNet, &IID_ISSLNet, &LIBID_SSLPOOLLib>
{
public:
CSSLNet();
~CSSLNet();


DECLARE_REGISTRY_RESOURCEID(IDR_SSLNET)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CSSLNet)
COM_INTERFACE_ENTRY(ISSLNet)
COM_INTERFACE_ENTRY(IObjectControl) //// POOL ////
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// ISSLNet
public:
STDMETHOD(Activate)(); //// POOL ////
STDMETHOD_(BOOL, CanBePooled)(); //// POOL ////
STDMETHOD_(void, Deactivate)(); //// POOL ////

CComPtr<IObjectContext> m_spObjectContext; //// POOL ////

STDMETHOD(Close)();
STDMETHOD(Init)(/*[out,retval]*/ long *lngRtn);
STDMETHOD(ConnectServer)(/*[out,retval]*/long *lngRtn); // 建立连接
STDMETHOD(get_TimeOut)(/*[out, retval]*/ long *pVal); //
STDMETHOD(put_TimeOut)(/*[in]*/ long newVal); // 超时时间
STDMETHOD(get_ServerIP)(/*[out, retval]*/ BSTR *pVal); //
STDMETHOD(put_ServerIP)(/*[in]*/ BSTR newVal); // 服务器IP
STDMETHOD(get_Port)(/*[out, retval]*/ long *pVal); //
STDMETHOD(put_Port)(/*[in]*/ long newVal); // 服务器端口
STDMETHOD(get_hSSLInfo)(/*[out, retval]*/ long *pVal); //
STDMETHOD(get_hSSL)(/*[out, retval]*/ long *pVal); // SSL Info
STDMETHOD(get_hSock)(/*[out, retval]*/ long *pVal); // Sock
STDMETHOD(get_CertPath)(/*[out, retval]*/ BSTR *pVal); // 证书路径
STDMETHOD(put_CertPath)(/*[in]*/ BSTR newVal);

private:
long m_SSL;
long m_SSLInfo;
long m_Sock;
long m_ServerPort;
long m_TimeOut;

char szServerIP[256];
char szCertPath[256];

HINSTANCE hinstDLL; // 动态链接库句柄

int InitSSL(void);
int DestroySSL(void);
long SSLMakeSession__(long sockfd,long SSLInfo,long timeout,long isServer);

};


//==================================================
//CPP文件部分:
//==================================================

STDMETHODIMP CSSLNet::get_TimeOut(long *pVal)
{
*pVal = m_TimeOut;
return S_OK;
}

STDMETHODIMP CSSLNet::put_TimeOut(long newVal)
{
m_TimeOut = newVal;
return S_OK;
}

STDMETHODIMP CSSLNet::Init(long *lngRtn)
{
// TODO: Add your implementation code here
*lngRtn = InitSSL();
return S_OK;
}

STDMETHODIMP CSSLNet::Close()
{
// TODO: Add your implementation code here
DestroySSL();
return S_OK;
}


HRESULT CSSLNet::Activate()
{
HRESULT hr = GetObjectContext(&m_spObjectContext);
if (SUCCEEDED(hr))
return S_OK;
return hr;

}

BOOL CSSLNet::CanBePooled()
{
return TRUE;
}

void CSSLNet::Deactivate()
{
m_spObjectContext.Release();
}



之所以发出上面的感叹,是因为我完全按照MSDN和网络上关于对象池COM+对象的例子去建立和实现,没有做任何添加和改动,结果和我提到的问题一样,所以现在感觉微软的MSDN就是在放屁.
Pipi0714 2006-05-08
  • 打赏
  • 举报
回复
www.codeproject.com上找找
it_manager 2006-05-08
  • 打赏
  • 举报
回复
微软的MSDN也看过了,唉,发现搞微软的东西就是麻烦,什么东西都不确定,还是基于java的开发方便一些,资料也多,不确定的问题也少一些,微软啊,什么时候能让你的追随者不再痛苦和无奈?
it_manager 2006-05-08
  • 打赏
  • 举报
回复
请大家帮帮我啊~~ 唉,搞这个东西,视力这几天都下降了,太压抑了~~~

痛苦啊,5.1没有休息一天,一直搞这个~~
it_manager 2006-05-08
  • 打赏
  • 举报
回复
嗯,谢谢pripor,不过我的代码都是按标准的做法搞的,很简单,和标准的没什么不同:


头文件部分:
/////////////////////////////////////////////////////////////////////////////
// CSSLNet
class ATL_NO_VTABLE CSSLNet :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CSSLNet, &CLSID_SSLNet>,
public IDispatchImpl<ISSLNet, &IID_ISSLNet, &LIBID_SSLPOOLLib>
{
public:
CSSLNet();
~CSSLNet();


DECLARE_REGISTRY_RESOURCEID(IDR_SSLNET)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CSSLNet)
COM_INTERFACE_ENTRY(ISSLNet)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

// ISSLNet
public:
STDMETHOD(Close)();
STDMETHOD(Init)(/*[out,retval]*/ long *lngRtn);
STDMETHOD(ConnectServer)(/*[out,retval]*/long *lngRtn); // 建立连接
STDMETHOD(get_TimeOut)(/*[out, retval]*/ long *pVal); //
STDMETHOD(put_TimeOut)(/*[in]*/ long newVal); // 超时时间
STDMETHOD(get_ServerIP)(/*[out, retval]*/ BSTR *pVal); //
STDMETHOD(put_ServerIP)(/*[in]*/ BSTR newVal); // 服务器IP
STDMETHOD(get_Port)(/*[out, retval]*/ long *pVal); //
STDMETHOD(put_Port)(/*[in]*/ long newVal); // 服务器端口
STDMETHOD(get_hSSLInfo)(/*[out, retval]*/ long *pVal); //
STDMETHOD(get_hSSL)(/*[out, retval]*/ long *pVal); // SSL Info
STDMETHOD(get_hSock)(/*[out, retval]*/ long *pVal); // Sock
STDMETHOD(get_CertPath)(/*[out, retval]*/ BSTR *pVal); // 证书路径
STDMETHOD(put_CertPath)(/*[in]*/ BSTR newVal);

private:
long m_SSL;
long m_SSLInfo;
long m_Sock;
long m_ServerPort;
long m_TimeOut;

char szServerIP[256];
char szCertPath[256];

HINSTANCE hinstDLL; // 动态链接库句柄

int InitSSL(void);
int DestroySSL(void);
long SSLMakeSession__(long sockfd,long SSLInfo,long timeout,long isServer);

};






cpp文件与对象池相关的部分(这些代码都是自动生成的,我也没有做过更改,其他的代码和对象池无关,所以就不贴出来了):

STDMETHODIMP CSSLNet::get_TimeOut(long *pVal)
{
*pVal = m_TimeOut;
return S_OK;
}

STDMETHODIMP CSSLNet::put_TimeOut(long newVal)
{
m_TimeOut = newVal;
return S_OK;
}

STDMETHODIMP CSSLNet::Init(long *lngRtn)
{
// TODO: Add your implementation code here
*lngRtn = InitSSL();
return S_OK;
}

STDMETHODIMP CSSLNet::Close()
{
// TODO: Add your implementation code here
DestroySSL();
return S_OK;
}
pripor 2006-05-03
  • 打赏
  • 举报
回复
把具体问题写出来
或者贴上代码大家帮你看

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧