2013-09-24 7 views
1

Я использую int-ip:tcp-connection-factory и int-ip:tcp-outbound-gateway для связи с внешним сервером. Протокол для большинства услуг, предлагаемых сервером, соответствует стандарту стиля запроса-ответа ... который отлично работает. Тем не менее, есть несколько ситуаций, когда мне нужно отправить запрос и ответа не ожидается.«Только для записи» по TCP-соединению с интеграцией с весной

Мой вопрос в том, как мне настроить каналы и соединения, чтобы я мог указать, ждать ли ответа? В настоящее время я не могу найти способ, и Spring всегда блокирует после отправки запроса, даже если я не ожидаю ответа.

EDIT: Как я уже говорил, я использовал tcp-outbound-channel-adapter. Мой конфигурационный файл имеет только следующее:

<int:channel id="requestChannel" /> 

<int-ip:tcp-outbound-channel-adapter 
    channel="requestChannel" connection-factory="client" /> 

<int-ip:tcp-connection-factory id="client" 
    type="client" host="smtp.gmail.com" port="587" single-use="false" 
    so-timeout="10000" /> 

А вот мой главный класс:

public final class Main { 

    private static final Logger LOGGER = Logger.getLogger(Main.class); 

    public static void main(final String... args) throws IOException { 
     LOGGER.debug("entered main()..."); 

     final AbstractApplicationContext context = new ClassPathXmlApplicationContext(
       "classpath:*-context.xml"); 

     MessageChannel requestChannel = context.getBean("requestChannel", MessageChannel.class); 
     requestChannel.send(MessageBuilder.withPayload("QUIT").build()); 

     LOGGER.debug("exiting main()..."); 
    } 

} 

Наконец это то, что я получаю в моем журнале:

11:57:15.877 INFO [main][com.together.email.Main] entered main()... 
11:57:16.295 INFO [main][org.springframework.integration.config.xml.DefaultConfiguringBeanFactoryPostProcessor] No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created. 
11:57:16.295 INFO [main][org.springframework.integration.config.xml.DefaultConfiguringBeanFactoryPostProcessor] No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created. 
11:57:16.480 INFO [main][org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory] started client 
11:57:16.480 INFO [main][org.springframework.integration.endpoint.EventDrivenConsumer] Adding {ip:tcp-outbound-channel-adapter} as a subscriber to the 'requestChannel' channel 
11:57:16.480 INFO [main][org.springframework.integration.channel.DirectChannel] Channel 'requestChannel' has 1 subscriber(s). 
11:57:16.480 INFO [main][org.springframework.integration.endpoint.EventDrivenConsumer] started org.springframework.integration.config.ConsumerEndpointFactoryBean#0 
11:57:16.480 INFO [main][org.springframework.integration.endpoint.EventDrivenConsumer] Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel 
11:57:16.481 INFO [main][org.springframework.integration.channel.PublishSubscribeChannel] Channel 'errorChannel' has 1 subscriber(s). 
11:57:16.481 INFO [main][org.springframework.integration.endpoint.EventDrivenConsumer] started _org.springframework.integration.errorLogger 
11:57:16.509 DEBUG [main][org.springframework.integration.channel.DirectChannel] preSend on channel 'requestChannel', message: [Payload=QUIT][Headers={timestamp=1381021036509, id=860ebe82-06c6-4393-95c7-0ece1a0a0e5d}] 
11:57:16.509 DEBUG [main][org.springframework.integration.ip.tcp.TcpSendingMessageHandler] org.springframework.integration.ip.tcp.TcpSendingMessageHandler#0 received message: [Payload=QUIT][Headers={timestamp=1381021036509, id=860ebe82-06c6-4393-95c7-0ece1a0a0e5d}] 
11:57:16.509 DEBUG [main][org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory] Opening new socket connection to smtp.gmail.com:587 
11:57:16.745 DEBUG [main][org.springframework.integration.ip.tcp.connection.TcpNetConnection] New connection smtp.gmail.com:587:550c9b68-10a0-442d-b65d-d25d28df306b 
11:57:16.748 DEBUG [main][org.springframework.integration.ip.tcp.TcpSendingMessageHandler] Got Connection smtp.gmail.com:587:550c9b68-10a0-442d-b65d-d25d28df306b 
11:57:16.749 DEBUG [pool-1-thread-1][org.springframework.integration.ip.tcp.connection.TcpNetConnection] TcpListener exiting - no listener and not single use 
11:57:16.750 DEBUG [main][org.springframework.integration.ip.tcp.connection.TcpNetConnection] Message sent [Payload=QUIT][Headers={timestamp=1381021036509, id=860ebe82-06c6-4393-95c7-0ece1a0a0e5d}] 
11:57:16.750 DEBUG [main][org.springframework.integration.channel.DirectChannel] postSend (sent=true) on channel 'requestChannel', message: [Payload=QUIT][Headers={timestamp=1381021036509, id=860ebe82-06c6-4393-95c7-0ece1a0a0e5d}] 
11:57:16.751 INFO [main][com.together.email.Main] exiting main()... 

Я дал протоколирование Спринга для отладки уровня, чтобы я мог дать вам более подробную информацию. Как видно из последней строки журнала, мои основные выходы. Однако, к сожалению, приложение не заканчивается, так как [pool-1-thread-1] продолжает работать. Эта нить оживает, как только send вызывается на requestChannel. Любая идея, что здесь происходит?

[В этом примере я отправляю сообщение SMTP QUIT, как только приложение подключится к Google. На практике я бы не начинал с QUIT. Например, в начале я могу начать с сообщения HELO. Я попытался подключиться к tcp-inbound-channel-adapter, чтобы получить ответ на сообщение, и это отлично работает. . Проблема с сообщениями, где я не ожидать ответа]

+2

Какая проблема при использовании '' для этих одноразовых случаев? И добавьте '' перед отправкой команды –

+0

Вы имели в виду '' является адаптером только для TCP? Я пробовал это, и он все еще блокируется в режиме чтения после отправки данных. Я что-то упускаю? – Tanvir

+0

Поделитесь своим, настройте, пожалуйста, и укажите, где вы наблюдаете блокировку –

ответ

1

Итак, я предлагаю вам ввести в <int-ip:tcp-connection-factory> некоторые «поддельные» ТАСК-исполнитель:

public class NullExecutor implements Executor { 

    public void execute(Runnable command) {} 
} 

В этом случае ваше соединение от AbstractClientConnectionFactory#obtainConnection() не будет настроено (запустится) для чтения из сокета.

Однако System.exit(0); как последняя строка вашего основных достаточно. В этом случае вся нить будет прекращена, если они не являются демонами.

+0

Спасибо Artem за решение. Это фактически решает проблему, о которой идет речь. В моем фактическом приложении я, однако, не смогу сделать System.exit (0), так как это будет веб-приложение, и новые SMTP-сессии должны будут создаваться каждый раз, когда это необходимо. Таким образом, поток будет похож на connect -> send HELO -> отправить другие команды протокола -> отправить QUIT -> disconnect для каждого сеанса. Мое приблизительное предположение, мне придется играть с автозапуском = «ложь», а затем запускать/останавливать адаптер по требованию. Если вы чувствуете, что это не сработает, или если вы сможете поделиться лучшим подходом, это будет очень признательно. – Tanvir

Смежные вопросы