【问题标题】:CXF client - TCP connection is closed between each requestCXF 客户端 - 在每个请求之间关闭 TCP 连接
【发布时间】:2020-08-06 19:43:54
【问题描述】:

我正在实现一个 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”,套接字是重新创建的。

我的电脑 (10.110.0.106) 正在关闭连接

使用的版本:

  • cxf-rt-ws-security 版本 3.3.6
  • cxf-rt-rs-client 版本 3.3.6

【问题讨论】:

    标签: java cxf onvif cxf-client


    【解决方案1】:

    终于找到了问题所在,代码不是系统故障。问题来自 Axis 设备。

    技巧是远程设备直接在 SOAP 响应(HTTP 消息)中关闭 TCP 流,在这种情况下,wireshark 不显示 [FIN, ACK]。但是如果我们直接查看 TCP 层,我们可以看到设置了“TCP FIN”标志:

    【讨论】:

      猜你喜欢
      • 2020-02-10
      • 2020-01-12
      • 1970-01-01
      • 2021-02-26
      • 2016-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-03
      相关资源
      最近更新 更多