节译,原文地址:
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