Java里面的Byte类型的取值范围是-128~127,而我们用C语言编出的程序每个字节储存的值可是0~255。要知道Java可没有Unsigned类型的数据。这个怎么解决?只能通过第三方来转发。
由于Java数据类型的取值范围的平台无关性,这导致了我们在16位的DSP芯片里编的程序所输出的数据传输到Java后台时会不会发生溢出这也是一个问题。这个怎么解决?只能通过第三方来转发。
而且由于Java是在虚拟机上运行的,它是解释型的,让Java SDK去处理CPU敏感任务,即不停的处理毫秒,微妙级的任务,呵呵,我没有这个勇气去冒这个险。
用Java RMI还是用基于com的Active控件来做网页的实时显示?从客户体验方面来说首选Active控件。如果用Java来做呵呵,后果不可想象。就目前为止,Java还没有找到能够改善客户体验的一种有效的方式。
以上就是为什么要用转发机制的动机,下面我们来看看ServerIn这个模块的功能。ServerIn这个模块是用来管理Active控件的,也就是说当用户打开实时监控页面运行Active控件时,Active如何建立?如何运行?这些要靠ServerIn模块来管理。其实ServerIn模块的功能和ClientIn模块的功能很象。只不过ClientIn是转发GPRSServer模块和Java后台之间的数据而ServerIn是转发GPRSServer和Active之间的数据。
我们来看看ServerIn两个主要的功能:
第一个功能:将GPRSServer模块的数据转发给Active。
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/None.gif)
9
![](/Images/OutliningIndicators/None.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/None.gif)
12
![](/Images/OutliningIndicators/None.gif)
13
![](/Images/OutliningIndicators/None.gif)
14
![](/Images/OutliningIndicators/None.gif)
15
![](/Images/OutliningIndicators/None.gif)
16
![](/Images/OutliningIndicators/None.gif)
17
![](/Images/OutliningIndicators/None.gif)
18
![](/Images/OutliningIndicators/None.gif)
19
![](/Images/OutliningIndicators/None.gif)
20
![](/Images/OutliningIndicators/None.gif)
21
![](/Images/OutliningIndicators/None.gif)
22
![](/Images/OutliningIndicators/None.gif)
23
![](/Images/OutliningIndicators/None.gif)
24
![](/Images/OutliningIndicators/None.gif)
25
![](/Images/OutliningIndicators/None.gif)
26
![](/Images/OutliningIndicators/None.gif)
27
![](/Images/OutliningIndicators/None.gif)
28
![](/Images/OutliningIndicators/None.gif)
29
![](/Images/OutliningIndicators/None.gif)
30
![](/Images/OutliningIndicators/None.gif)
31
![](/Images/OutliningIndicators/None.gif)
32
![](/Images/OutliningIndicators/None.gif)
33
![](/Images/OutliningIndicators/None.gif)
34
![](/Images/OutliningIndicators/None.gif)
35
![](/Images/OutliningIndicators/None.gif)
36
![](/Images/OutliningIndicators/None.gif)
37
![](/Images/OutliningIndicators/None.gif)
38
![](/Images/OutliningIndicators/None.gif)
39
![](/Images/OutliningIndicators/None.gif)
40
![](/Images/OutliningIndicators/None.gif)
这个消息函数还是比较简单的,基本上和上一节列出的消息函数差不多。不过我们要注意的是24行,这行作用是找到相应的SocketID,SocketID是什么?当很多个Active控件连接到ServerIn模块的时候,每个Active控件在ServerIn模块中都会留下唯一的标识。这个标识就是SocketID,其实就像是数据库中一张表中的关键字一样。找到相应的SocketID其实就是找到了唯一的Acitve,也就是找到了发命令的那台电脑(客户机)。当然也会出现一种情况,就是多台电脑(客户机)在对同一台下位机进行操作,这个时候该怎么做呢?看看我们的22~30行,是个大循环,原来只要符合要求的SocketID我们都会去转发数据。
当然说到现在我们还没有提到到哪个地方找到这些SocketID吧,其实我们一直在和SoketID链接池打交道,24行就使从SocketID链接池找到SocketID。当然如何编写一个链接池,你们可能要看看我写的《设计模式(四)Singleton》篇里对于Pooling的Delphi实现了。当然我在链接池里保存的是很多个结构。每个结构里储存着SocketID和其他一些重要的信息。这个链接池同时具有查找、增加、删除、修改、初始化等功能。我们24行就是它的查找功能函数。总体来说,你们可以将链接池看成存放n多个Active的信息的仓库。
为了论述简洁性,我就不累诉了,防止你们对总体框架产生混淆。
第二个功能,将Active控件的数据转发给ServerIN。![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/None.gif)
9
![](/Images/OutliningIndicators/None.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/None.gif)
12
![](/Images/OutliningIndicators/None.gif)
13
![](/Images/OutliningIndicators/None.gif)
14
![](/Images/OutliningIndicators/None.gif)
15
![](/Images/OutliningIndicators/None.gif)
16
![](/Images/OutliningIndicators/None.gif)
17
![](/Images/OutliningIndicators/None.gif)
18
![](/Images/OutliningIndicators/None.gif)
19
![](/Images/OutliningIndicators/None.gif)
20
![](/Images/OutliningIndicators/None.gif)
21
![](/Images/OutliningIndicators/None.gif)
上面的大部分内容是针对链接池中的结构进行的判别操作,你们看看就行了。不要求你们理解。我们看最后一行,这行其实我们在其他模块中也出现过很多次。这行的含义是将数据发送给哪个模块,ServerInSendToClientInInfo这个参数含义很明显,将数据传递给ClientIn模块,好像我们刚刚讲的ServerIn模块它的功能是将数据转发给GPRSServer模块阿?这里怎么传递给了ClientIn呢?这里我偷懒了,因为上一节我给你们讲过Java后台发送出来的数据是不能直接传递给下位机的,需要进行转换,那么这个转换功能在哪个模块作了呢?是在ClientIn模块作了。这里可能你们要混淆了。其实整个系统有两种转换,第一种是下位机(也就是我们上面讲的DSP硬件系统)将数据传递给GPRSServer的向上传递过程,在这个过程中数据的转换工作是在GPRSServer模块中进行的,转换完成之后,将数据转发给ClientIn,ClientIn这个时候什么都不做,它只是简单的把数据扔给Java后台就OK了。第二种是Java后台将数据传递给ClientIn模块的向下传递过程。在这个过程中数据的转换工作是在ClientIn中进行的,还记不记得上一章讲的接口了,那个接口就是负责具体转换工作的。但ClientIn将数据转换好之后,就发送给GPRSServer或SERVER(无线电模块)这两个模块收到数据后也是什么都不做,直接将数据扔给下位机。
那么既然我已经在ClientIn中做好了那个接口,我为什么还要在ServerIn中再做一回呢同样的事呢,所以我直接将数据发送给了ClientIn,欺骗ClientIn,让ClientIn认为是Java后台发送的数据,ClientIn一旦收到这样的数据,它当然要进行转换和转发工作了。当然这样做性能上会收到一些影响。但影响不太大,是微秒级的。
至此ServerIn模块的大体结构就完成了。下一节我将会给你们讲Active的实现机理。