Instant Messaging java(第三章)04

3.3.2 服务的焦点,packetQueue

packetQueue类是一个受限的响应集合的基本数据结构类。然而,他是服务器端的信息流的焦点。Packet从客户端聚集到packetQueue。然后packet按照packet的元素名发散出去。许多操作方法能够被服务器激活,并且同步到packetQueue

Comand操作设计模式:

 

For those familiar with design patterns, our packet handling system is a minor

variation on the Command Processor design pattern.9

“The Command Processor design pattern separates the request for a service

from its execution. A command processor component manages requests as

separate objects, schedules their execution, and provides additional services

such as the storing of request objects for later undo.

 

 

 

 

 

 

 

 

 

 


jabber服务中,xml解析充当命令控制器的作用,接受请求和转换

在我们的jabber服务,XML解析动作作为command控制器接受请求,转换xml流到命令。QueeueThread充当命令处理机获得paceket并调度他们的执行。不管像不像命令处理模式,packets是不会自己处理他们自己的运行。双重功能的命令处理供应者和命令处理代替我们的packet处理类,提供我们的整个的包处理功能。

使用comandprocessor模式的好处是:

l       请求触发的可扩展性——支持选择启动的方法是的能够很容易的桥连我们的jabber服务和其它message系统。

l       请求的操作和数量上的可扩展性——快速改变jabber协议是非常重要的。

l       相关服务的可编程——在特殊情况下,我们只要稍稍修改QueueThread就能够容易的记录packets和重放jabber会话。

l       应用的可测试性——QueueThread是一个极好的接入点,为我们测试xml解析和packet处理。一旦开启,记录和重放session是一个巨大的帮助。

l       并发——包和他们的处理是一个相对分离的计算。当线程同时执行时,QueueThread能够容易的分配处理。

Commander processor模式有一些缺陷:

l       效率的损耗——转换数据格式和提供中间处理步骤需要而外的计算时间的存储空间。

l       潜在着过多的命令类——大部分时候,我们避免把所有的包表现为单一的,一般的paceket类。我们为简单性而降低了一半的呈现效率。另外,一个packet类能够呈现不定数量的packet类。我们的服务必须建立额为的逻辑来垂腭这些包。

PacketQueue必须:

l       存储包——接受packet对象推入packetQueue的底

l       回收包——允许packet对象退出packetQueue,并移除它

l       线程安全——无障碍的允许多线程同步从packetQueeue pushpull packet

l       提供线程同步——如果PacketQueue是空的,调整pull包之前让调用者停止一会儿直到一个新的packet进入队列,或者线程终止。线程能够同步的使用它们的操作和保存服务资源。

操作packet对象的线程能够有效的不断的从packetqueue拉出packet对象。PacketQueue自己必须确保这些工作的线程只能够在packetQueue正常有效的情况下执行。

packetQueeue的对象是非常简单的。一个java.util.LinkedList对象,用来存储Packets和一点用来支持服务器多线程环境的基本要素。

在下面高亮的部分提示了方法push()和pull()是线程安全保护的。每一个push()方法的调用时引起了notifyAll()唤醒等待的pull()处理线程。Pull()方法的定时器在队列是空的时候调用wait()方法。

public class PacketQueue {

//Actual storage is handled by a java.util.LinkedList

LinkedList queue = new LinkedList();

public synchronized void push(Packet packet){

queue.add(packet);

notifyAll();

}

public synchronized Packet pull(){

try {

while (queue.isEmpty()) {

wait();

}

} catch (InterruptedException e){

return null;

}

return (Packet)queue.remove(0);

}

}

loop是必须的,因为push()方法调用notifyAll(),唤醒所有等待的pull()。如果仅仅一个packet被推进队列,第一个线程执行移除从队列中。所有其他等待的线程继续运行,队列是空的,他们定时wait(),直到下一个包的到来。

如果你不能理解java线程代码,你可以信任这些工作,写一些测试验证一下,或者学习关于java线程的知识。我已经尽力将本书的中关于thread的代码最小化,但是服务代码倾向于沉重的线程。如果你希望学习到线程,有几个很好的书可以看。另外,java在线文档也提供免费指导。

现在,我们看看用jabberInputHandle类处理xml解析。

3.3.5java中的 SAX 解析(略)

3.4包处理和服务器线程

我最终需要的jabber服务器,包括服务包处理类和服务器端线程。包处理是继承自PacketListerer接口的简单对象,处理包对象。我们用的包处理类实现我们知道的jabber协议。

在这一章,我们将创建三个packet处理类:

l       当未关闭的<stream:stream>发送时一个OpenStreamhandler类为每一个连接创建Sessiong对象。

l       一个简单的messagehandler类,实现Jabber包路由初始版本。

l       当发送关闭标签<stream:stream>时候,CloseStreamhandler类经关闭连接。

服务的线程系统有三个类组成,每一个类代表一个线程执行:

l       Server——主应用程序类和主执行线程。这个类创建jabber服务socket和接受新的jabber客户连接。

l       ProcessTread——服务器线程类接受连接处理。他创建一个jabberInputHandler和一个输入xml流过程。ProcessThread线程处理和连接一一相对。

l       QueueThread——这个线程类从PacketQueeue得到包然后他打发给适当的包处理类。在jabber服务中仅仅有一个活动的queueThread对象。

在同一时间有许多线程在服务上执行,然而,只有三种类型的需要你的关心,并且只有ProcessThread有超过一个的实例在执行。理解服务工作的最后办法,看看3.6图,显示了服务器上都发生了什么。

我们看看服务的主应用首先启动。他的首要任务是创建QueueThread类。新的queueThread立即调用pull()接受PacketQueue的包。QueueThread定时是因为队列中没有包。服务然后等待这用java.net.ServerSocekt.accept()调用连接。

在服务器上一个客户连接。这促使服务器创建一个processThread。这个ProcessTrheadsaX解析开启解析输入xml流和我们的JabberInputhandler类。当客户端发送xml包到服务器,ProcessTrhead的解析类创建包对象并调用push()加入到PacketQueue

队列中新的Packet唤醒QueueThreadQueeuThread确定包已经被推入队列,然后用当前处理类处理它。包处理发送输出xml包到客户端。

注意仅有一个服务线程接受连接,并且一个QueueThread处理从packetQueue的包对象。然而,每一个客户链接有一个活动的processThread。有共享执行线程的方法处理输入的客户连接。另外,服务器有许多的包处理线程。然而,在我们的服务中,我们使他们尽量的简单。

从服务的主类创建QueueThreadProcessThread,我们首先看到有两个帮助线程类,在运行服务助力额之前。QueueThread是个更加的复杂,我们就在这开始。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值