Jax-WS service 异步 service call 概念及原理

在旧的基于JAX-RPC的webservice编程model中,是不支持异步的service 调用的,在最新的Jax-ws webservice 编程model中,加入了对webservice的异步调用的支持。
首先我来讲一下它的原理,大家不要以为在异步的调用下,从client到server 之间的soap message 流也是异步的,其实不是,Soap/Http 协议在同步跟异步的调用下是一样的,都是客户端的service在运行时打开一个connectin,发送请求,然后接收返回,这些都在同一个connection中。这种方式对我们有什么影响呢? 从客户端程序的角度来讲,没有影响,客户端的编程模型是由WSDL中的messages跟port types 来定义的,只要这些东西没有改变,request 跟response是不是在同一个Tcp/ip 的session 中来发送对与我们来说没由影响,然后从架构跟资源的角度来讲,对我们的影响就大了,把连接层的资源跟应用层的程序运行状态绑定起来是由许多弊端的,假如在异步调用时,程序运行出现了异常,将会导致连接层的资源被一直占用,这样会极大的影响我们程序的,稳定性,可靠性,资源的使用跟性能。
所以WebSphere Application Server V7提供了一个简单的实现,能够实现真实的异步soap Message,下面我们会详细讲解。

当前Jax-ws 提供了两种编程模型。
1.Polling client
2.CallBack client
下面我们分别就这两种编程模型进行讲解。
当你启用了异步调用功能时,当你用工具生成stub时,Jax-ws会给你每个operation 生成三个方法

 a.An synchronous method
 b.An asynchronous polling method
 c.An asynchronous callback method
以下是一个生成的client-side Interface example
下面来详细讲述polling clients:
在这种异步模式下,当异步clients调syHelloAsync 方法,将会返回一个response object, 这个response Object 提供了一些方法来让你查询是否response已经返回,是否取消一个response,以及取得返回的response.如以下实例代码,你可以用sayHelloAsync .isDone来检查是否response已经返回。用sayHelloAsync .get()来取得返回的一个包装过的对象(SayHelloResponse),里面包含真实的返回值。

import javax.xml.ws.Response;
import itso.hello.HelloMessenger;
import itso.hello.HelloMessengerService;
import itso.hello.SayHelloResponse;
public class HelloAsyncPollingClient {
public static void main(String... args) throws Exception {
HelloMessengerService service = new HelloMessengerService();
HelloMessenger port = service.getHelloMessengerPort();
Response<SayHelloResponse> sayHelloAsync =
port.sayHelloAsync("Thilde");
//判断是否已经返回
while ( ! sayHelloAsync.isDone() ) {
// Do something useful for now
}
// Web service endpoint has now responded:
//取得包装过的返回对象
SayHelloResponse sayHelloResponse = sayHelloAsync.get();
//取得真实返回值
String message = sayHelloResponse.getReturn();

System.out.println(message);
}
}

 
Callbacking 模型的client 示例代码如下:

import itso.hello.HelloMessenger;
import itso.hello.HelloMessengerService;
import itso.hello.SayHelloResponse;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
public class HelloAsyncCallbackClient {
public static void main(String... args) throws Exception {
HelloMessengerService service = new HelloMessengerService();
HelloMessenger port = service.getHelloMessengerPort();
port.sayHelloAsync("Teresa", new AsyncHandler<SayHelloResponse>()
{
public void handleResponse(Response<SayHelloResponse> res) {
try {
SayHelloResponse response = res.get();

String message = response.getReturn();
System.out.println(message);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}

 
由以上代码可知,callback类型的client要传入一个javax.xml.ws.AsyncHandler类型的匿名内部类,当soap Message 到达时,Jax-ws会调handleResponse这个方法来处理response.
以上就时Polling Client 跟Callback型的异步client的概念及使用示例,开始我也讲过,实际上这种所谓的异步调用有很大的弊端的。在最新的websphere  V7上提供一种解决方案。提供了一种真实的异步message的交换方式。在使用时你需要给client-side proxy配置一个特别的属性,示例如下:

Map<String, Object> requestContext =
((BindingProvider)port).getRequestContext():
// Configure the client for wire-level asynchronous message exchange
requestContext.put("com.ibm.websphere.webservices.use.async.mep",
true);

 

当你启用这种异步message交换机制时,client端会在request发出后在一个单独的channel上来监听和接收response message.当然,client在发出request时,会使用WS-Addressing 来向server提供 ReplyTo endpoint reference(ERP),当请求发出去以后当前的这个connection就会关闭,当servicer处理完请求时,它会根据client端提供的ERP(ReplyTo endpoint reference)重新初始化一个connection 来发送一个response.
当然了,这种机制也有弊端就时可移植性太差,只能在Websphere V7上使用。

你可能感兴趣的:(编程,webservice,SOAP,websphere,Exchange)