当前位置:首考文秘网>范文大全 > 教学设计 > 基于Java的远程数据驱动设计实现

基于Java的远程数据驱动设计实现

时间:2023-05-18 16:10:07 教学设计 来源:网友投稿


打开文本图片集

摘要:提出了在Client/Server架构下,根据数据库的数据变化来驱动远程客户端应用程序的设计方案;该方案基于Java 、Socket、JNI、IPC以及Windows消息机制等技术,克服了传统对数据库定时扫描的缺点,文章最后给出了基于PowerBuilder客户端应用程序的一个具体实现。

关键词:Socket IPC;JNI;Windows消息机制;Java

1、问题的提出

当基于集中式Client/Server架构的应用系统需要根据数据库中数据的变化情况来决定是否启动相应的处理程序时,以往采用了由应用程序定时对数据库进行扫描的方式。这种定时的由客户端对数据库服务器进行扫描的方法有如下缺点:

①造成服务器的负荷增大,特别是当定时扫描在数据操作频繁时进行,还造成服务器性能下降;

②网络流量增多;

③定时扫描并不能实时的处理随机出现的数据变化,造成处理滞后。特别是对于数据更新无规律的应用,时间间隔的设定更是困难,因为时间间隔设定过大,会降低数据的实时性,时间间隔设定过小,又增加了网络负担和服务器负荷。

但目前主流数据库都没有提供当数据库数据发生变化时及时通知客户端应用的直接方法。

2、解决方案的设计思想

针对以上问题,我们提出了一种当数据库信息发生变化时能及时通知远程客户端应用程序的解决方案,克服了由远程客户端应用程序定时扫描数据库的弊端。该解决方案的核心思想是:利用数据库的触发器机制,在数据发生变化后调用存储过程,然后在存储过程中调用Java程序,Java程序实现Socket通信,在客户端利用消息机制将数据变化的消息通知应用程序,应用程序收到消息后触发相应事件执行相应操作,如图1。

2.1数据库的触发机制

大型关系数据库都提供了触发器(Trigger)机制,ORACLE数据库触发器定义了当一些数据库相关事件发生时数据库应采取的动作。触发器可用于完整性控制,审计表中的数据变化或者监控数据的变动等。触发器体由PL/SQL代码块组成。

2.2由存储过程调用Java类访问外部资源

由于整个应用系统的整体架构是基于集中式Client/Server模式,客户端编程语言是非Java的,Oracle数据库中没有提供直接访问外部资源的机制,但提供了对Java的支持,可利用LoadJava方法,将Java程序装载到Oracle数据库中作为数据对象供存储过程调用,利用Java程序访问外部资源。

2.3通过Java程序实现服务器与远程客户端的Socket通讯

当数据变化达到一定条件后,Oracle通过Socket通知远程客户端,远程客户端的Socket服务程序通过JNI调用C语言的动态链接库,获取本地非Java应用程序的进程信息,利用Windows的消息机制。将Oracle的控制信息传入非Java应用程序,由非Java应用程序响应消息,触发相应的事件作出相应的处理,从而达到数据驱动远程客户端应用的目的。

3、关键技术

3.1基于Java的Socket通讯

利用TCP/IP协议在客户机和服务器之间建立Socket连接是网络通讯的一种模式,这种通讯模式首先分别在客户机和服务器端创建Socket,并建立一个可靠的Socket连接,然后双方在这个Socket连接上进行数据交互。使用Socket进行远程通讯的方式有3种:

① 字节流套接字(StreamSocket):TCP/IP协议族中TCP协议使用此类接口,它提供面向连接的 (建立虚电路 )、无差错的、发送顺序一致的、包长度不限和非重复的网络信包传输;

② 数据报套接字(DatagramSocket):TCP/IP协议族中的UDP(User Datagram Protocol)协议使用此类接口,它是无连接的服务,以独立的信包进行网络传输,信包最大长度为 32KB,传输不保证顺序性、可靠性和无重复性,通常用于单个报文传输或可靠性要求不高的场合;

③ 原始数据包套接字(Raw Socket):提供对网络下层通信协议 (如IP协议 )的直接访问,一般不是提供给普通用户的。主要用于开发新的协议或用于提取协议较隐蔽的功能。

其中字节流套接字是最常用的套接字类型。在Java语言中利用java.net包中的Socket类和ServerSocket类创建客户端和服务端Socket。在服务端采用了多线程技术使得服务端的Socket能同时为多个客户端请求服务,极大的提高了运行效率。

3.2 JNI调用

由于客户端应用程序采用的开发工具不同,例如PowerBuilder、VisualBasic等,要获取正在运行中的非Java应用程序的信息,由于Java又没有提供诸如指针等概念,因此借助C语言来获取应用程序的进程信息、以及利用windows的消息机制向非Java应用程序传递消息,来实现对非Java应用程序的控制,而Java调用C语言需要用到JNI接口标准。JNI(Java Native Interface)是Java与其他编程语言的集成编程接口,又称为本地方法接口。它使运行于Java虚拟机上的Java代码与其它语言编写的库和应用程序能够互相调用。JNI允许本地方法建立、使用和更新Java对象,调用Java方法和引用Java类。JNI也允许Java代码调用C、C++等语言编写的程序和库。Invocation API(JNI 的一部分)可以用来将 Java 虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用 Java 代码。由于在运行环境(Runtime)下,只有动态链接库或者共享对象库能够被Java虚拟机引导,而静态库和压缩库不能在运行环境下被调用。所以在Java中调用其它编程语言生成的代码是通过调用动态链接库或者共享对象库的方式来实现的,而在其它语言中调用Java对象是通过引用指向Java对象的指针来实现的。

3.3 消息机制

Windows消息提供了应用程序与应用程序之间、应用程序与Windows系统之间进行通讯的手段[ 3]。应用程序要实现的功能由消息来触发,并靠对消息的响应和处理来完成。Windows系统中有两种消息队列,一种是系统消息队列,另一种是应用程序消息队列。计算机的所有输入设备由 Windows监控,当一个事件发生时,Windows先将输入的消息放入系统消息队列中,然后再将输入的消息拷贝到相应的应用程序队列中,应用程序中的消息循环从它的消息队列中检索每一个消息并发送给相应的窗口函数中。一个事件的发生,到达处理它的窗口函数必须经历上述过程。消息队列中消息的结构(MSG)为:

typedef struct tagMSG{

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

DWORD time;

POINT pt;

}MSG;

其中第一个成员变量是用以标识接收消息的窗口的窗口句柄;第二个参数便是消息标识号,如WM_PAINT;第三个和第四个参数的具体意义同message值有关,均为消息参数。前四个参数是非常重要和经常用到的,至于后两个参数则分别表示邮寄消息的时间和光标位置(屏幕坐标)。把消息传送到应用程序有两种方法:一种是由系统将消息“邮寄(post)”到应用程序的“消息队列”这是“进队消息”Win32 API有对应的函数:PostMessage(),此函数不等待该消息处理完就返回;而另一种则是由系统在直接调用窗口函数时将消息"发送(send)"给应用程序的窗口函数,属于“不进队消息”对应的函数是SendMessage()其必须等待该消息处理完后方可返回。

Windows 应用程序创建的每个窗口都在系统核心注册一个相应的窗口函数,窗口函数程序代码形式上是一个巨大的switch 语句,用以处理由消息循环发送到该窗口的消息,窗口函数由Windows 采用消息驱动的形式直接调用,而不是由应用程序显示调用的,窗口函数处理完消息后又将控制权返回给Windows。

4、解决方案的实现

4.1 基于Java的Socket通讯服务

public class MonitorSocketServer {

ServerSocket s = new ServerSocket(PORT);

try{

while(true){

Socket socket = s.accept();

try{

new ServerOneJabber(socket);

} catch(IOException e){

socket.close();

}

}

以上是服务端Socket的创建过程,它主要是负责对指定的端口进行监听,如果有请求进来则响应,调用相应的处理类。

4.2客户端程序

这是Socket客户端的创建过程,它主要是与Socket服务端进行通讯。我们的应用是要根据Oracle数据库中数据变化而进行实时的触发通讯,因此在用户修改了数据提交数据库后,由数据库触发器直接调用Socket通知远程服务端启动。Oracle的触发器是不能访问Java代码的,只能通过存储过程来访问,而存储过程要使用Java代码只能通过Oracle提供的工具LoadJava将客户端MonitorSocketClient装载到Oracle数据库中,作为一个数据对象供Oracle调用:

LoadJava-u scott/tiger-r-v-f c:/MonitorSocketClient.java

4.3存储过程调用客户端程序

CREATE OR REPLACE PROCEDURE Call_Monitor(ip varchar2,port varchar2,message varchar2)

as language java

name " MonitorSocketClient.main(java.lang.string[])";

接下来,Socket服务端需要根据传入的参数对客户端进行控制:由于Java没有指针等概念,无法获得我们的应用程序进程号,因此采用JNI编程,调用C++函数来获取程序进程,操作应用程序进行相应的处理:

public class ControlClientApplication{

public native long getProcessInfo(String);

public native int dealRemoteControl(String applicationName , );

public static void main (String[ ] args){

System.loadLibray(“ControlObject”);

ControlObject CObject = new ControlObject;

long ProcessId = getProcessInfo(args[ 0]);

编译后使用javah将ControlClientApplication.class文件编译成为一个C++的头文件(ControlClientApplication.h)。这个工具被设计成用来创建头文件,该头文件为在java 源代码文件中所找到的每个native方法定义 C 风格的函数。我们用C++编写一个实现:

#include “ControlClientApplication.h”

#include

#include

HANDLE hProcessSnapShot = NULL;

PROCESSENTRY32 pe32 = {0};

int iLen;

CString strSpace = “”;

hProcessSnapShot = (HANDLE)CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

pe32.dwSize = sizeof(PROCESSENTRY32);

Process32First(hProcessSnapShot,&pe32);

do {

strSpace = “”;

strAppName = pe32.szExeFile;

for(iLen = 0; iLen<60-strAppName.GetLength(); iLen++)

strSpace = strSpace + “”;

strAppName = strAppName + strSpace;

} while(Process32Next(hProcessSnapShot,&pe32));

CloseHandle(hProcessSnapShot);

在Powerbuilder的主界面窗口中加入刷新事件(pbvm_paint)的处理方法:

Choose Case Messae.LongParm

Case 0

Case 1

Open(w_netwatch)

End Choose

5、结论

以上方法作者已在开发的财政横向网信息系统调用财政集中支付系统中应用,证明是有效的。但由于采用了Windows的消息机制、动态链接库,因此整个解决方案必须基于Windows平台,跨平台性能不佳。

参考文献

1、Tom Portfolio.Java Stored Procedures Developer’s Guide.Oracle Corporation.1999

2、Bruce Eckel,Thinking in Java, president, MindView, Inc.2002

3、刘丹华,黄道君.利用套接字开发网络通信程序.微机发展.2003年1月

(作者单位:湖南省财政厅)

推荐访问:驱动 数据 设计 java

版权所有:首考文秘网 2015-2024 未经授权禁止复制或建立镜像[首考文秘网]所有资源完全免费共享

Powered by 首考文秘网 © All Rights Reserved.。备案号:冀ICP备15026071号-91