《ice实例学习》由会员分享,可在线阅读,更多相关《ice实例学习(12页珍藏版)》请在金锄头文库上搜索。
1、ICE实例学习:Lets Chat! 节译时间:2010-02-01 19:42 来源: 作者:秩名 点击: 399 次注意,对于 ICE3.3, PHP和 Ruby只提供了客户端的 Run Time。我们在考虑当连接的客户如何从服务器获得消息时,必须要想到这一点。对于消息发布,有两种通信模型:推模型和拉模型收藏到: TAG: 服务器编程 ICE 聊天室 节译,原文地址:http:/ Web浏览器作为客户端。6)客户端可能网络带宽有限,所以应该尽量减少网络流量。只支持单个聊天室。(多个聊天室只是代码多了点,并没有增加任何难度)。设计在本文中,将会演示多种客户端的设计和实现。包括:1)C+命令行
2、客户端;2)JAVA SWing GUI 客户端;3).NET WPF 客户端;4)PHP 网页客户端;5)Silverlight 网页客户端;注意,对于 ICE3.3, PHP和 Ruby只提供了客户端的 Run Time。我们在考虑当连接的客户如何从服务器获得消息时,必须要想到这一点。对于消息发布,有两种通信模型:1)推模型:略2)拉模型:略推模型比较简单,容易实现,我们的 Chat 客户端中,C+,Java, .Net, Silverlight(0.3)都使用该模型。PHP 客户端使用拉模型。推模型定义 每个客户端中提供一个 ChatRoomCallback 类型的 ICE对象到服务器。
3、当发生事件时,服务器调用该对象的操作通知客户。SLICE 定义如下:/ Slice module Chat / Implemented by clients interface ChatRoomCallback ami void init(Ice:StringSeq users); ami void join(long timestamp, string name); ami void leave(long timestamp, string name); ami void send(long timestamp, string name, string message); ; ;1)当用户首
4、次连接到聊天室时,服务器调用 init 操作. users 参数告诉用户目前连接到聊天室的所有用户信息。2)有用户连接到聊天室时,服务器调用 join 操作。3)有用户断开连接时,服务器调用 leave 操作。4)有用户发送消息时,服务器调用 send 操作。注意设计使用异步事件。元数据指令 ami 标明服务器异步调用回调操作。当客户端行为异常时,这对服务器是一个保护:客户端可能长时间阻塞,服务器调用期间不会因此失去对线程的控制。与防火墙协作略.Glacer2是 ICE针对这种情况的预建的解决方案,它扮演一个服务器前端。Glacer2具有以下特征:1)支持会话概念,API 支持认证机制,可实现
5、自定义的会话创建和认证。2)单个 Glacer2可进行任意数量的服务器和客户端转发。服务器只要有一个端口接受外来连接,而不用管具体服务器个数。3)对于具有防火墙的客户端,服务器也可调用其提供的回调。因为 Glacer2 会话概念是面向连接的,只有当客户端同 Glacer2的连接打开时,更精确的说,同 Glacer2保持一个激活的会话时,服务器才可以对客户进行回调。换句话说,当客户端同 Glacer2失去连接,Glacer2 自动销毁会话。为了阻止客户端到 Glacer2的连接被意外关闭,客户端必须要禁用ACM(Automic Connection Management, 自动连接管理)。而且,
6、Glacer2 通常对长时间空闲的会话设置超时。当聊天室长时间没有动作时,为了防止 Glacer2销毁会话,客户端必须周期性进行激活,比如,调用 ice_ping, 来对 Glacer2的会话超时进行重置。Chat客户端通过服务器提供的 ChatSession 接口来和服务器通信。 ChatSession 从 Glacer2:Session派生。/ Slice module Chat exception InvalidMessageException string reason; ; interface ChatSession extends Glacier2:Session void set
7、Callback(ChatRoomCallback* cb); ami long send(string message) throws InvalidMessageException; ; ;这就是推模型,Chat 客户端调用 ChatSession的 send来发送消息,服务器调用每一个客户的 ChatRoomCallback的 send操作进行分发。拉模型定义.略服务器实现:服务器使用 C+。注意它的结构:类 ChatRoom 实现了大部分的应用逻辑。为了支持推模型与拉模型,服务器实现了类 ChatSession 和类 PollingChatSession。 ChatRoom 调用 Ch
8、atRoomCallbackAdapter 对象的 send 函数来传递客户消息,该对象隐藏了两种模型之间的差异。ChatRoom 实现:ChatRoom是一个普通的 C+对象,而不是一个 Servant./ C+ class ChatRoomCallbackAdapter /* */ ; typedef IceUtil:Handle ChatRoomCallbackAdapterPtr; class ChatRoom : public IceUtil:Shared public: void reserve(const string void unreserve(const string vo
9、id join(const string Ice:Long send(const string private: typedef map ChatRoomCallbackMap; ChatRoomCallbackMap _members; set _reserved; IceUtil:Mutex _mutex; ; typedef IceUtil:Handle ChatRoomPtr;成员_reserverd 是一个字符串集合,它存储已经建立回话,但是还没有加入聊天室的客户名。_members 存储当前聊天室的所有用户(已经调用过 join函数的用户)。成员函数 reserve 和 unres
10、erve 维护 _reserved 集合。/ C+ void ChatRoom:reserve(const string& name) IceUtil:Mutex:Lock sync(_mutex); if(_reserved.find(name) != _reserved.end() | _members.find(name) != _members.end() throw string(The name + name + is already in use.); _reserved.insert(name); void ChatRoom:unreserve(const string& na
11、me) IceUtil:Mutex:Lock sync(_mutex); _reserved.erase(name); join操作添加用户到聊天室。/ C+ void ChatRoom:join(const string& name, const ChatRoomCallbackAdapterPtr& callback) IceUtil:Mutex:Lock sync(_mutex); IceUtil:Int64 timestamp = IceUtil:Time:now().toMilliSeconds(); _reserved.erase(name); Ice:StringSeq name
12、s; ChatRoomCallbackMap:const_iterator q; for(q = _members.begin(); q != _members.end(); +q) names.push_back(*q).first); callback-init(names); _membersname = callback; UserJoinedEventPtr e = new UserJoinedEvent(timestamp, name); for(q = _members.begin(); q != _members.end(); +q) q-second-join(e); sen
13、d实现,同 join实现非常类似:/ C+ Ice:Long ChatRoom:send(const string& name, const string& message) IceUtil:Mutex:Lock sync(_mutex); IceUtil:Int64 timestamp = IceUtil:Time:now().toMilliSeconds(); MessageEventPtr e = new MessageEvent(timestamp, name, message); for(ChatRoomCallbackMap:iterator q = _members.begin(
14、); q != _members.end(); +q) q-second-send(e); return timestamp; 类 ChatRoomCallbackAdapter / C+ class ChatRoomCallbackAdapter : public IceUtil:Shared public: virtual void init(const Ice:StringSeq virtual void join(const UserJoinedEventPtr virtual void leave(const UserLeftEventPtr virtual void send(co
15、nst MessageEventPtr ;推模式 CallbackAdapter 实现: class SessionCallbackAdapter : public ChatRoomCallbackAdapter public: SessionCallbackAdapter(const ChatRoomCallbackPrx& callback, const ChatSessionPrx& session) : _callback(callback), _session(session) void init(const Ice:StringSeq& users) _callback-init_async(new AMICallback(_session), users); void join(const UserJoinedEventPtr