eXile 的专栏

[T] ICE实例学习:Let's Chat! 节译 (1)

节译,原文地址:http://www.zeroc.com/articles/index.html

需求

      1)一个典型的聊天室应用,使用客户器/服务器架构,客户发送消息到中心服务器,然后,消息发送给其它客户。
      2)尽量减少服务器管理,甚至可以不需要。
      3)通信必须安全,通过公共网络时必须要保护个人隐私。
      4)当客户端和服务器有防火墙保护时也能正常运行,客户端不用修改它的网络或者防火墙设置。
      5)客户端可以在各种平台上利用多种语言实现,比如说利用Web浏览器作为客户端。
      6)客户端可能网络带宽有限,所以应该尽量减少网络流量。
      只支持单个聊天室。(多个聊天室只是代码多了点,并没有增加任何难度)。

设计

      在本文中,将会演示多种客户端的设计和实现。包括:
      1)C++命令行客户端;
      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对象到服务器。当发生事件时,服务器调用该对象的操作通知客户。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)当用户首次连接到聊天室时,服务器调用 init 操作.     users参数告诉用户目前连接到聊天室的所有用户信息。
     2)有用户连接到聊天室时,服务器调用 join 操作。
     3)有用户断开连接时,服务器调用 leave 操作。
     4)有用户发送消息时,服务器调用 send 操作。
     注意设计使用异步事件。元数据指令 ["ami"] 标明服务器异步调用回调操作。当客户端行为异常时,这对服务器是一个保护:客户端可能长时间阻塞,服务器调用期间不会因此失去对线程的控制。

与防火墙协作
      略......

      Glacer2是ICE针对这种情况的预建的解决方案,它扮演一个服务器前端。Glacer2具有以下特征:
      1)支持会话概念,API支持认证机制,可实现自定义的会话创建和认证。
      2)单个Glacer2可进行任意数量的服务器和客户端转发。服务器只要有一个端口接受外来连接,而不用管具体服务器个数。
     3)对于具有防火墙的客户端,服务器也可调用其提供的回调。

     因为 Glacer2会话概念是面向连接的,只有当客户端同Glacer2的连接打开时,更精确的说,同Glacer2保持一个激活的会话时,服务器才可以对客户进行回调。换句话说,当客户端同Glacer2失去连接,Glacer2自动销毁会话。为了阻止客户端到Glacer2的连接被意外关闭,客户端必须要禁用ACM(Automic Connection Management, 自动连接管理)。而且,Glacer2通常对长时间空闲的会话设置超时。当聊天室长时间没有动作时,为了防止Glacer2销毁会话,客户端必须周期性进行激活,比如,调用 ice_ping, 来对Glacer2的会话超时进行重置。

     Chat客户端通过服务器提供的 ChatSession接口来和服务器通信。 ChatSession 从Glacer2::Session派生。
// Slice 
module Chat 

exception InvalidMessageException 

    
string reason; 
}; 
 
interface ChatSession extends Glacier2::Session 

    
void setCallback(ChatRoomCallback* cb); 
    [
"ami"long send(string message) throws InvalidMessageException; 
}; 
};

      这就是推模型,Chat客户端调用ChatSession的send来发送消息,服务器调用每一个客户的ChatRoomCallback的send操作进行分发。

拉模型定义

TODO


posted on 2009-03-25 23:52 eXile 阅读(2202) 评论(0)  编辑 收藏 引用 所属分类: 网络开发ICE


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2009年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

常用链接

留言簿(18)

随笔分类

随笔档案

服务器编程

搜索

最新评论

阅读排行榜

评论排行榜