ICE专题:ICE实现聊天室
来源:互联网 发布:三众软件 编辑:程序博客网 时间:2024/05/20 12:51
对于网络应用来说,比较简单就是发送请求和等待回应模型,我把这种模式称之为单工模型,服务器没有办法主动通知客户端发生了什么,只有被动的等待客户端来请求并回应,最经典的就是HTTP服务,对于这种模型来说这已经够了,但对于服务器与客户之间的互动来说,这种就不行了,得需要双工模型,即服务器与客户之间的相互通知。对于这种模型,最能说明问题的就是一个聊天室了,一个房间有多人聊天,一个人所说的话得经过服务器而通知其它人,这种就需要服务器与客户端的一个简单互动了,但这也足以说明问题了。ICE的出现使这种模型变得简单,下面我就来介绍一下如何使用ICE来开发聊天室。 如上图所述,我们所要做的工作就是将一台客户端发出的信息,广播到其它的客户端上,就是这么一个简单的操作。为了达到这种目的,必须在服务器端和客户端都开一个监听端口,用来双方交互,同时服务器端还要接受客户端的请求,成为一个信息HUB。 因为ICE本身就是平台无关的,所以在什么平台上编缉并不影响其它平台。首先要写一个slice文件,定义服务。 module FloorSpace { interface CallBack { void GetInput(string content); }; dictionary<string,CallBack *> CacheMap; interface Floor { bool Register(string name); void SetInput(string content); void Unregister(); void SetupCallback(CallBack * cp); }; }; CallBack是用来定义客户端的回调服务,Floor是用来定义服务器端的服务。 定义好slice文件后,比如叫做floor.ice,用slice2cpp floor.ice生成服务。它会生成floor.h 和floor.cpp两个文件,这两个文件定了服务接口和代理接口。 需要一个文件用来从floor.h中继承Floor接口中的各种服务,需要一个文件用来从floor.h中继承CallBack接口中的服务。 class FloorI:virtual public Floor { virtual bool Register(const string & name,const Current & context); virtual void SetInput(const string & content,const Current & context); virtual void Unregister(const Current & context); virtual void SetupCallback(const CallBackPrx & prx,const Current & context); CacheMap m_cache_map; }; class CallBackI:virtual public CallBack { public: virtual void GetInput(const string & content,const Current & context); }; 当然需要将FloorI中的虚函数实现,这就是你的服务真正所在了。 bool FloorI::Register(const string & name,const Current & context) { if(m_cache_map.find(name)!=m_cache_map.end()) return 0; else m_cache_map[name]; return 1; } void FloorI::Unregister(const Current & context) { Context::const_iterator q=context.ctx.find("user_name"); if(q!=context.ctx.end()) { CacheMap::iterator p; if((p=m_cache_map.find(q->second))!=m_cache_map.end()) m_cache_map.erase(p); } } void FloorI::SetupCallback(const CallBackPrx & prx,const Current & context) { Context::const_iterator p=context.ctx.find("user_name"); if(p!=context.ctx.end()) { m_cache_map[p->second]=prx; } } void FloorI::SetInput(const string & content,const Current & context) { Context::const_iterator q=context.ctx.find("user_name"); if(q!=context.ctx.end()) { CacheMap::iterator p; for(p=m_cache_map.begin();p!=m_cache_map.end();++p) { if(p->first!=q->second) { Context ctx; ctx["user_name"]=q->second; try { p->second->GetInput(content,ctx); } catch(ConnectionRefusedException e) { m_cache_map.erase(p); cout<<" 挂了"<<endl; } catch(NullHandleException e) { m_cache_map.erase(p); cout<<" 没有诚意"<<endl; } } } } } CallBack服务具体定义: void CallBackI::GetInput(const string & content,const Current & context) { Context::const_iterator q=context.ctx.find("user_name"); if(q!=context.ctx.end()) { cout<<"["<<q->second<<" say]"<<content<<endl; } } 这样我们的聊天室服务器端和客户端的服务定义实现完毕。剩下就是写服务器和客户端了,服务器的实现很简单,因为这是ICE的框架: int ServerApp::run(int argc,char * argv[]) { shutdownOnInterrupt(); ObjectAdapterPtr adapter=communicator()->createObjectAdapter("Floor.Server"); adapter->add(new FloorI,stringToIdentity("floor")); adapter->activate(); communicator()->waitForShutdown(); return EXIT_SUCCESS; } 就这么几行代码,可以实现网络联结和服务创建。客户端的实现: int ClientApp::run(int argc,char * argv[]) { shutdownOnInterrupt(); Ice::PropertiesPtr properties = communicator()->getProperties(); const char * buf="Floor.Proxy"; string proxy=properties->getProperty(buf); if(proxy.empty()) { cerr << argv[0] << ": property `" << buf << "' not set" << endl; return EXIT_FAILURE; } cout<<proxy<<endl; FloorPrx floorprx=FloorPrx::checkedCast(communicator()->stringToProxy(proxy)); if(!floorprx) { cerr << argv[0] << ": invalid proxy" << endl; return EXIT_FAILURE; } string user_name; cout<<"name : "; cin>>user_name; cout<<endl; if(floorprx->Register(user_name)==0) { cout<<user_name<<" has been registered"<<endl; return EXIT_FAILURE; } Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Floor.Client"); adapter->add(new CallBackI, Ice::stringToIdentity("callbackReceiver")); adapter->activate(); Context ctx; ctx["user_name"]=user_name; floorprx=FloorPrx::uncheckedCast(floorprx->ice_newContext(ctx)); CallBackPrx cbp=CallBackPrx::uncheckedCast(adapter->createProxy(stringToIdentity("callbackReceiver"))); floorprx->SetupCallback(cbp); string content; cout<<"please input something"<<endl; cout<<"["<<user_name<<" say]"; while(cin>>content) { cout<<endl; floorprx->SetInput(content); cout<<"["<<user_name<<" say]"; } floorprx->Unregister(); } 实现的就是一个人说话,将他说的话传到服务器,服务器将其广播到其它用户,功能实现完毕。 总结:ICE使你不用关心网络如何联结,端口如何定义,你所要关心的就是服务如何实现,而这正是你想要的。当你知道想做什么,但一想到网络通讯的复杂程度,可能就没有信心了,ICE正好使它成为可能。学习ICE是一件很愉快的事。 文件: 大小: 下载:
ice_floor_callback.rar
10KB
下载
- ICE专题:ICE实现聊天室
- ICE专题:实现简单的聊天室(一)
- ICE:实现简单的聊天室
- ICE专题:ICE简介
- 用ICE实现一个简单的聊天室
- 用ICE实现一个简单的聊天室
- ICE专题:学习ICE 3.0
- ICE学习demo-聊天室
- ice
- ICE
- ICE
- Ice
- ICE
- ice
- ICE专题:JDBC桥接器
- ICE专题:ICE的5个服务
- ICE专题:编译环境构建
- ICE专题:网络服务平台比较
- ICE专题:实现简单的聊天室(一)
- 解决ExtJs TextField maxLength后还是可以输入
- VC6.0中Invalidate与UpdataWindow的差别
- 视频聊天源码【旗舰版(上)】
- ICE专题:JDBC桥接器
- ICE专题:ICE实现聊天室
- Java程序员的推荐阅读书籍
- MiniGui演示程序常见错误
- 利用VS2005创建WINCE 6.0平台
- liferay5.0.1用户登录后的跳转
- 送礼物送什么好
- ICE专题:编译环境构建
- 终端下的俄罗斯方块游戏tetris
- ICE专题:网络服务平台比较