CXF 客户端 - TCP 连接在每个请求之间关闭
CXF client - TCP connection is closed between each request
我正在实现一个 SOAP 客户端,一般工作正常,但我发现了一个陷阱,因为在每次请求时 TCP 连接都关闭(由我)。
这是次优的,使用 HTTPS 时更糟,因为每个请求都会交换证书。
httpconduit的创建和SOAP服务的调用
public static void test(final String destination) {
System.setProperty("javax.xml.soap.SAAJMetaFactory", "com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl");
TLSClientParametersFactory tlsClientParametersFactory = new TLSClientParametersFactory
.Builder()
.acceptAllCerts()
.build();
JAXRSClientFactoryBean clientFactoryBean = new JAXRSClientFactoryBean();
clientFactoryBean.setAddress(destination);
WebClient webClient = clientFactoryBean.createWebClient();
ClientConfiguration config = WebClient.getConfig(webClient);
HTTPConduit conduit = config.getHttpConduit();
HTTPClientPolicy client = conduit.getClient();
client.setConnection(ConnectionType.KEEP_ALIVE);
client.setConnectionTimeout(TimeUnit.MINUTES.toMillis(60));
conduit.setTlsClientParameters(tlsClientParametersFactory.createTlsClient());
Media media = createFactory(Media.class, conduit, tlsClientParametersFactory, destination);
// The call of the soap service, with the expectation to have the same TCP connection used.
List<Profile> profiles = media.getProfiles();
List<Profile> profiles2 = media.getProfiles();
List<Profile> profiles3 = media.getProfiles();
List<Profile> profiles4 = media.getProfiles();
List<Profile> profiles5 = media.getProfiles();
创建SOAP端口
private static <T> T createFactory(final Class<T> clazz,
final Conduit conduit,
final TLSClientParametersFactory factory,
final String destination) {
Map<String, Object> props = new HashMap<>();
props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
props.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallback.class.getName());
props.put(WSHandlerConstants.USER, "test");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props);
JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
proxyFactory.setAddress(destination);
proxyFactory.setServiceClass(clazz);
SoapBindingConfiguration config = new SoapBindingConfiguration();
config.setVersion(Soap12.getInstance());
proxyFactory.setBindingConfig(config);
proxyFactory.setConduitSelector(new PreexistingConduitSelector(conduit));
Map<String, Object> properties = proxyFactory.getProperties();
if (properties == null) {
properties = Maps.newHashMap();
}
properties.put(Client.KEEP_CONDUIT_ALIVE, true);
proxyFactory.setProperties(properties);
T t = proxyFactory.create(clazz);
TLSClientParametersFactory.setSsClientParametersToPort(factory, t);
return t;
}
我做错了什么??
注意:完成新请求后连接将关闭。否则 TCP 连接保持活动状态。
另一个输入
并非所有目的地目标都存在该问题。例如,如果我使用设备 "AXIS A1001 Network Door Controller",系统无需重新创建 tcp 套接字即可工作(tcp 对话已着色)
但是我用的是"AXIS P5534 Network Camera",socket是重新创建的
我的电脑 (10.110.0.106) 正在关闭连接
使用的版本:
- cxf-rt-ws-security 版本 3.3.6
- cxf-rt-rs-client 版本 3.3.6
终于找到问题了,代码不是系统问题。问题来自 Axis 设备。
技巧是远程设备直接在 SOAP 响应(HTTP 消息)中关闭 TCP 流,在这种情况下 wireshark 不显示 [FIN, ACK]。但是如果我们直接查看 TCP 层,我们可以看到设置了 "TCP FIN" 标志:
我正在实现一个 SOAP 客户端,一般工作正常,但我发现了一个陷阱,因为在每次请求时 TCP 连接都关闭(由我)。
这是次优的,使用 HTTPS 时更糟,因为每个请求都会交换证书。
httpconduit的创建和SOAP服务的调用
public static void test(final String destination) {
System.setProperty("javax.xml.soap.SAAJMetaFactory", "com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl");
TLSClientParametersFactory tlsClientParametersFactory = new TLSClientParametersFactory
.Builder()
.acceptAllCerts()
.build();
JAXRSClientFactoryBean clientFactoryBean = new JAXRSClientFactoryBean();
clientFactoryBean.setAddress(destination);
WebClient webClient = clientFactoryBean.createWebClient();
ClientConfiguration config = WebClient.getConfig(webClient);
HTTPConduit conduit = config.getHttpConduit();
HTTPClientPolicy client = conduit.getClient();
client.setConnection(ConnectionType.KEEP_ALIVE);
client.setConnectionTimeout(TimeUnit.MINUTES.toMillis(60));
conduit.setTlsClientParameters(tlsClientParametersFactory.createTlsClient());
Media media = createFactory(Media.class, conduit, tlsClientParametersFactory, destination);
// The call of the soap service, with the expectation to have the same TCP connection used.
List<Profile> profiles = media.getProfiles();
List<Profile> profiles2 = media.getProfiles();
List<Profile> profiles3 = media.getProfiles();
List<Profile> profiles4 = media.getProfiles();
List<Profile> profiles5 = media.getProfiles();
创建SOAP端口
private static <T> T createFactory(final Class<T> clazz,
final Conduit conduit,
final TLSClientParametersFactory factory,
final String destination) {
Map<String, Object> props = new HashMap<>();
props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
props.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
props.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallback.class.getName());
props.put(WSHandlerConstants.USER, "test");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props);
JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean();
proxyFactory.setAddress(destination);
proxyFactory.setServiceClass(clazz);
SoapBindingConfiguration config = new SoapBindingConfiguration();
config.setVersion(Soap12.getInstance());
proxyFactory.setBindingConfig(config);
proxyFactory.setConduitSelector(new PreexistingConduitSelector(conduit));
Map<String, Object> properties = proxyFactory.getProperties();
if (properties == null) {
properties = Maps.newHashMap();
}
properties.put(Client.KEEP_CONDUIT_ALIVE, true);
proxyFactory.setProperties(properties);
T t = proxyFactory.create(clazz);
TLSClientParametersFactory.setSsClientParametersToPort(factory, t);
return t;
}
我做错了什么??
注意:完成新请求后连接将关闭。否则 TCP 连接保持活动状态。
另一个输入 并非所有目的地目标都存在该问题。例如,如果我使用设备 "AXIS A1001 Network Door Controller",系统无需重新创建 tcp 套接字即可工作(tcp 对话已着色)
但是我用的是"AXIS P5534 Network Camera",socket是重新创建的
我的电脑 (10.110.0.106) 正在关闭连接
使用的版本:
- cxf-rt-ws-security 版本 3.3.6
- cxf-rt-rs-client 版本 3.3.6
终于找到问题了,代码不是系统问题。问题来自 Axis 设备。
技巧是远程设备直接在 SOAP 响应(HTTP 消息)中关闭 TCP 流,在这种情况下 wireshark 不显示 [FIN, ACK]。但是如果我们直接查看 TCP 层,我们可以看到设置了 "TCP FIN" 标志: