CXF клиент - TCP-соединение закрывается между каждым запросом - PullRequest
1 голос
/ 23 апреля 2020

Я реализую один SOAP клиент, общая работа в порядке, но я заметил одну ловушку, потому что при каждом запросе TCP-соединение закрывается (мной).

Это неоптимально, и хуже, когда используется HTTPS, потому что сертификаты обмениваются каждым запросом.

Создание httpconduit и вызов SOAP service

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», система работает без воссоздания сокета tcp (диалог tcp раскрашен)

Axis A1001 same socket

Но я использую «Сетевую камеру AXIS P5534», гнездо воссоздается.

Multiples request against network camera

И это мой p c (10.110.0.106) который 'закрывает соединение enter image description here

Используемая версия:

  • cxf-rt-ws-security версия 3.3.6
  • cxf-rt-rs-client версия 3.3.6

1 Ответ

0 голосов
/ 24 апреля 2020

Наконец-то я нашел проблему, код не неисправная система. Проблема исходит от устройства Axis.

Хитрость заключается в том, что удаленное устройство закрывает поток TCP непосредственно в ответе SOAP (сообщение HTTP), и в этом случае wireshark не отображает [FIN, ACK ]. Но если мы посмотрим непосредственно на уровень TCP, то увидим, что флаги «TCP FIN» были установлены:

TCP FIN is SOAP response

...