Hprose for Java客户端(三)
异步调用
下面我们来开始另一个重要的话题,那就是异步调用。
异步调用相对于同步调用来说确实要难以掌握一些,但是在很多情况下我们却很需要它。那究竟什么时候我们需要使用异步调用呢?
很多时候我们并不确定在进行远程调用时是否能够立即得到返回结果,因为可能由于带宽问题或者服务器本身需要对此调用进行长时间计算而不能马上返回结果给客户端。这种情况下,如果使用同步远程调用,客户端执行该调用的线程将被阻塞,并且在主线程中执行同步远程调用会造成用户界面冻结,这是用户无法忍受的。这时,我们就需要使用异步调用。
虽然您也可以使用多线程加同步调用来完成异步调用(实际上Hprose的异步调用也是如此实现的),但您不必这样做。您可以直接使用Hprose提供的异步调用方式,这将更加简单。
通过invoke方法进行异步调用
通过invoke方式进行异步调用跟同步调用差不多,唯一的区别就是异步调用多了一个回调方法参数。
因为java本身不能向C/C++那样传递函数或方法指针,也不能向C#那样传递方法委托,所以在java中invoke的回调方法是以接口HproseCallback来表示的,它只有一个方法:
package hprose.exam;import hprose.client.HproseHttpClient;import hprose.common.HproseCallback;import java.io.IOException;import java.util.HashMap;import java.util.List;import java.util.Map;interface ITest { Map<String, String> swapKeyAndValue(Map<String, String> strmap, HproseCallback callback); void swapKeyAndValue(Map<String, String> strmap, HproseCallback callback, boolean byRef); void getUserList(HproseCallback callback, Class returnType);}public class ClientExam10 { public static void main(String[] args) throws IOException { HproseHttpClient client = new HproseHttpClient(); client.useService("http://localhost:8084/HproseExamServer/Methods"); final ITest test = (ITest) client.useService(ITest.class, "ex2"); Map<String, String> map = new HashMap<String, String>(); map.put("January", "Jan"); map.put("February", "Feb"); map.put("March", "Mar"); map.put("April", "Apr"); map.put("May", "May"); map.put("June", "Jun"); map.put("July", "Jul"); map.put("August", "Aug"); map.put("September", "Sep"); map.put("October", "Oct"); map.put("November", "Nov"); map.put("December", "Dec"); test.swapKeyAndValue(map, new HproseCallback() { public void handler(Object result, Object[] args) { synchronized (test) { Map<String, String> map = (Map<String, String>)args[0]; Map<String, String> map2 = (Map<String, String>)result; System.out.println("byVal:"); System.out.println(map); System.out.println(map2); System.out.println(); } } }); test.swapKeyAndValue(map, new HproseCallback() { public void handler(Object result, Object[] args) { synchronized (test) { Map<String, String> map = (Map<String, String>)args[0]; Map<String, String> map2 = (Map<String, String>)result; System.out.println("byRef:"); System.out.println(map); System.out.println(map2); System.out.println(); } } }, true); test.getUserList(new HproseCallback() { public void handler(Object result, Object[] args) { List<User> users = (List<User>)result; for (User user : users) { System.out.printf("name: %s, ", user.getName()); System.out.printf("age: %d, ", user.getAge()); System.out.printf("sex: %s, ", user.getSex()); System.out.printf("birthday: %s, ", user.getBirthday()); System.out.printf("married: %s.", user.isMarried()); System.out.println(); } System.out.println(); } }, null); test.getUserList(new HproseCallback() { public void handler(Object result, Object[] args) { User[] users = (User[])result; for (User user : users) { System.out.printf("name: %s, ", user.getName()); System.out.printf("age: %d, ", user.getAge()); System.out.printf("sex: %s, ", user.getSex()); System.out.printf("birthday: %s, ", user.getBirthday()); System.out.printf("married: %s.", user.isMarried()); System.out.println(); } System.out.println(); } }, User[].class); System.in.read(); }}