`
suoyihen
  • 浏览: 1352228 次
文章分类
社区版块
存档分类
最新评论

学习JavaFX Script,第二部分:使用RMI进行远程通信

 
阅读更多
原文地址:http://java.sun.com/developer/technicalArticles/scripting/javafxpart2/

本系列的第一部分向Java程序员介绍了JavaFX脚本编程语言的语法及语义。本文在您对JavaFX脚本认知的基础上进行描述,调用Java平台的远程方法调用(Remote Method Invocation,Java RMI)类库,使JavaFX图形用户界面(GUI)可以远程通信。在JavaFX脚本中使用RMI是非常直接的,使用简单快捷的方式就可以完成演示和测试客户端-服务器功能。

在NetBeans中新建一个JavaFX脚本工程(Creating a JavaFX Script Project in the NetBeans IDE)

首先,在NetBeans集成开发环境(IDE)5.5.1中新建一个JavaFX Scrip工程,如果你还从来没有这样做过,那就一定要阅读一下这篇优秀的文章《Getting Started With JavaFX Script Language (for Swing Programmers)》,里面有详细的描述。然而,如果你了解这些方式,并且已经从Netbeans Beta Update Center下载并安装了JavaFX模块,那么你将会明白这里总结的重点。
1、从NetBeans的主菜单中选择File菜单,接着选择Net Project。
2、在New Project向导对话框中,在Categories面板中选择General,在Project面板中选择Java Application。点击Next。
3、在Project Name域中输入JavaFXClient。
4、在Project Location中,点击Browse,然后指定存储工程的位置。
5、取消对Set as Main Project和Create Main Class复选框的选择,然后点击Finish。
现在,使用IDE创建一个名为HelloServer的JavaFX Script文件。
1、在Projects窗口中,右键点击JavaFXClient > Source Packages节点,选择New > File/Folder。
2、在Categories面板中,选择Other,接着在File Types面板中,选择JavaFX File。然后点击Next。现在,当你在Projects窗口中调用主工程节点的New或者Source Packages节点时,JavaFX文件类型应该出现在可用的文件类型列表中。
3、在New JavaFX File向导中的Name and Location页中,File Name中输入MyClient,Folder域中输入src/client。注意,现在新建的文件名会出现在Created File域中。
4、点击Finish完成工程的新建。
5、在Projects窗口中,右键点击JavaFXClient节点,选择Properties。
6、在Properties对话框的Categories面板中,选择Run。
7、在Arguments域中输入脚本的名称:client.MyClient,点击OK。
此时将会在JavaFXClient工程的client目录中创建一个名为MyClient.fx的空JavaFX Script文件。此时,让这个文件为空,接着设置项目的另外一部分——完成RMI服务器的设置后将重新返回这里。

使用远程方法调用(RMI)进行客户端--服务器通信(Client-Server Communication with Remote Method Invocation(RMI))

Java远程方法调用(Java RMI)是用来实现远程等价对象调用的Java应用程序接口(API)。使用RMI开发分布式程序比用socket要简单,因为开发者不需要定义协议,而定义协议往往是消耗时间又容易出错的工作。
使用RMI,开发者有从本地类文件调用本地方法的假象,其实,参数被发送到远程目标并被解释,然后结果又被发送回调用者。因为JavaFX Script可以调用Java对象,所有RMI就是一个让JavaFX客户端进行远程通信的既快捷又简单的工具。
使用RMI开发一个分布式JavaFX Script程序包含一下步骤:
1、定义一个远程接口。
2、实现远程接口。
3、开发服务器。
4、使用Java开发一个针对JavaFX Script的连接助手。
5、创建一个调用上述连接助手的JavaFX Script客户端。
本文作者压缩了前三步,它们来自于Qusay Mahmoud的优秀文章《Distributed Java Programming With RMI and CORBA》,因为它们和RMI的传统Java实现没有区别。最后两步针对JavaFX Script做了修改。然而,在你深入每一步时,你需要为服务器新建一个NetBeans IDE工程。
在NetBeans中,按如下步骤操作:
1、从File菜单中选择New Project。应该可以看到类似图1的一个对话框。
在NetBeans IDE5.5.1中新建一个工程
图1 在NetBeans5.5.1 中新建一个工程
2、在Categories列表中,选择General。在Projects列表中,选择Java Application。点击Next。应该可以看到一个类似图2的对话框。
在NetBeans IDE中自定义新工程
图2 在NetBeans IDE中自定义新工程
3、在Project Name中输入JavaRMIServer。选择适当的文件夹保存项目,然后取消对Set as Main Project的选择。最后,点击Finish按钮。这就创建了一个名为JavaRMIServer的Java工程。

定义一个远程接口(Define a Remote Interface)
现在,在server包中创建一个名为ServerInterface的Java接口,如代码示例1所示。接口ServerInterface包含了一个方法,ping(),它获取一个String参数,返回一个hello加上该参数组成的字符串。
代码示例1
packageserver;

importjava.rmi.Remote;
importjava.rmi.RemoteException;

publicinterfaceServerInterfaceextendsRemote...{

publicStringping(StringfileName)throws
RemoteException;

}
和任何一个RMI程序一样,ServerInterface必须符合下述要求:
1、必须继承Remote接口。
2、为了客户端可以加载一个实现了Remote接口的远程对象,必须声明为public。
3、接口中的每一个方法(本例中只包含了一个方法)必须抛出java.rmi.RemoteException。

实现远程接口(Implement the Remote Interface)
接下来的步骤是创建一个实现了ServerInterface的类。一个示例实现如代码示例2所示。注意,除了实现ServerInterface外,ServerImpl类还要继承UnicasRemoteObject。这说明ServerImpl类是用来创建一个单一的、不可复制的远程对象,它使用RMI默认的TCP传输进行通信。这可能是无论任何时候使用RMI时需要做的所有事情。
示例代码2
packageserver;

importjava.io.*;
importjava.rmi.*;
importjava.rmi.server.UnicastRemoteObject;

publicclassServerImplextendsUnicastRemoteObject
implementsServerInterface...{

privateStringname;

publicServerImpl()throwsRemoteException...{
super();
}


publicStringping(Strings)...{
return"Hello"+s;
}


}

开发服务器(Develop the Server)
第三步是开发服务器。这个类将成为服务器程序的入口,因为它包含了main()方法。服务器必须完成以下三个任务:
1、创建RMI注册处(RMI registry)。
2、创建一个远程的实例——本例中,是ServerImpl。
3、注册使用RMI注册处创建的对象。
一个示例实现如代码示例3所示。
代码示例3
packageserver;

importjava.rmi.*;
importjava.rmi.registry.LocateRegistry;

publicclassServerMain...{

publicstaticvoidmain(Stringargv[])...{

try...{

LocateRegistry.createRegistry(
1099);

ServerInterfaces
=newServerImpl();
Naming.rebind(
"//127.0.0.1/Server",s);

}
catch(Exceptione)...{
System.out.println(
"Server:"+e.getMessage());
e.printStackTrace();
}

}

}
Naming.rebind("//127.0.0.1/Server", s)语句假设RMI注册处运行在默认的端口上,即代码示例3中在LocateRegistry.createRegistry()语句定义的1099端口。可是,如果RMI注册处运行在不同的端口上——例如,更改注册位置创建语句为LocateRegistry.createRegistry(4500)——那么你就要相应地将绑定语句过更改为:
Naming.rebind("//127.0.0.1:4500/Server",s)
另外,特别需要注意的是,地址127.0.0.1是一个专用的localhost地址,它假定RMI注册位置和服务器运行在同一台机器上。如果它们不是运行在同一台机器上,只需要简单的更改rebind()方法中的地址,和RMI注册处的IP地址相适应。

使用Java开发一个针对JavaFX Script的连接助手(Develop a Java Technology-Based Connection Helper for JavaFX Script)
接下来步骤是在JavaFXClient工程中完成的,它和传统RMI程序不同:现在必须创建一个Java连接助手。这个连接助手远程调用远程接口——ServerInterface——中指定任何方法,然后把结果返回到调用它的JavaFX Script。为了完成这个任务,连接助手首先需要从RMI注册处获得远程对象的引用。一旦获得了引用,就可以调用适当的方法。
代码示例4中给出了实现。注意,这只是一个简单的静态方法,通过它JavaFX Script可以获得远程ServerInterfacde的实现对象的引用。
代码示例4
packageclient;

importjava.rmi.*;
importserver.ServerInterface;

publicclassConnectionHelper...{

publicstaticServerInterfacegetConnection()
throwsException
...{
return(ServerInterface)
Naming.lookup(
"rmi://127.0.0.1:1099/Server");
}


}

再一次需要注意,这段代码假定RMI注册处和客户端运行在同一台机器上。如果不是这样,修改IP地址——如果需要,同时修改端口——使二者匹配。
一旦把这些信息输入到NetBeans IDE工程中,你可能想弄明白这个工程是如何访问在JavaRMIServer工程创建的ServerInterface类的。理论上讲,在客户端和服务器端工程之间共享了一个包含RMI接口的独立JAR文件,或者建立了一个动态类的加载机制——关于此后是如何操作的更多信息参考技术提示中的“Dynamic Class Loading in RMI”部分。
然而,为了简单期间,你可以只完成其中的一个:
1、复制ServerInterface的源文件到JavaFXClient工程的client中。
2、修改JavaFXClient工程的属性,使其包含JavaRMIProject工程。
无论使用哪种方式,都要在源码顶部中增加适当的导入语句,如代码示例4所示。

创建调用连接助手的JavaFX Script客户端(Create the JavaFX Script Client That Class Upon the Connection Helper)
最后,代码示例5给出了尅用来创建JavaFX Script客户端的代码,该客户端通过RMI和远程服务器通信。将代码示例5中的代码复制到MyClient.fx文件中。
代码示例5

importjava.lang.*;
importjavafx.ui.*;
importjava.rmi.*;

importserver.ServerInterface;
importclient.ConnectionHelper;


classButtonClickModel...{
attributenumClicks:Number;
}


varmodel
=newButtonClickModel();

varwin
=Frame...{
width:
200
content:GridPanel
...{
border:EmptyBorder
...{
top:
30
left:
30
bottom:
30
right:
30
}

rows:
3
columns:
1
vgap:
10
cells:
[Button
...{
text:
"ClicktomakeRMIconnection!"
mnemonic:I
action:operation()
...{

try...{

varremoteServer:ServerInterface
=
ConnectionHelper.getConnection();

varresults
=remoteServer.ping("Test");
System.out.println(
"response:{results}");
model.numClicks
++;

}
catch(e:Exception)...{
System.out.println(
"exception:{e}");
}

}

}
,

Label
...{
text:bind
"NumberofRMIconnections:{model.numClicks}"

}

]
}

visible:
true
}
;

现在,编译和运行服务端工程。接着,运行客户端工程。应该可以看到类似图3所示的界面。点击“Click to make RMI connection”按钮。一段时间后,检查是否有响应信息输出到了NetBeans IDE底部的输出控制台上。每连接成功一次,按钮下面的计数器就会增加一。
JavaFX客户端调用远程服务器
图3 JavaFX客户端调用远程服务器

总结(Conclusion)


本文简单介绍了使用JavaFX Script和RMI进行客户端--服务器编程的方法。在本文中,JavaFX平台应用在整个客户端中。本系列的第三部分将讨论使用JavaFX平台和Java API for XML Web Services(JAX-WS)处理客户端--服务器通信的方式。以后的文章中将使用已有的客户端-服务器Java代码集成到JavaFX Script平台中。

更多信息参考(For More Information)

  • Learning JavaFX Script, Part 1: An Introduction to JavaFX Script for Java Programmers.
  • Download the NetBeans IDE 5.5.1 JavaFX Script Client project from this article.
  • Download the NetBeans IDE 5.5.1 Java RMI Server project from this article.
  • JavaFX Pad -- This JNLP starts the JavaFX Pad application, which allows you to iteratively enter JavaFX code and watch the results at the same time.
  • The OpenJFX Web Site -- The official site for JavaFX technology.
  • Getting Started With the JavaFX Script Language (for Swing Programmers) -- This excellent tutorial shows you how to use the graphical widgets in the JavaFX scripting language. Because many of these widgets map directly to the underlying Swing components, readers who are familiar with programming Swing will be able to read quickly through this document.
  • JavaFX Script 2D Graphics Tutorial -- Similar to JavaFX Pad, this JNLP will help you learn to use the 2D graphics functionality inside JavaFX technology.
  • The JavaFX Script Programming Language Reference -- The official reference for the programming language.
  • 分享到:
    评论

    相关推荐

    Global site tag (gtag.js) - Google Analytics