2013-09-24 54 views
1

我正在使用int-ip:tcp-connection-factoryint-ip:tcp-outbound-gateway與外部服務器進行通信。服務器提供的大多數服務的協議遵循標準的請求 - 響應風格......這非常有效。但是,在少數情況下,我只需要發送請求並且沒有響應。通過與Spring集成的TCP連接'只寫'

我的問題是,如何配置我的通道和連接,以便我可以指定是否等待響應?目前我找不到方法,Spring發送請求後總是阻塞,即使我不期待迴應。

編輯: 如建議,我用了一個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()... 

我已經設置Spring的日誌調試級別,以便我可以給你更多的細節。從日誌的最後一行可以看到,我的主要退出。但是,不幸的是,應用程序不會因爲[pool-1-thread-1]繼續運行而終止。此線程在requestChannel上調用send後即生效。任何想法這裏發生了什麼?

[在本例中,一旦應用程序連接到Google,我將發送SMTP QUIT消息。在實踐中,我實際上不會以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),因爲它將是一個Web應用程序,並且每次需要時都必須實例化新的SMTP會話。因此,流程將像連接 - >發送HELO - >發送其他協議命令 - >發送QUIT - >斷開每個會話。我粗略猜測,我將不得不玩弄auto-startup =「false」,然後根據需要啓動/停止適配器。如果你覺得這不起作用,或者如果你可以分享更好的方法,將非常感激。 – Tanvir