2016-06-22 19 views
3

Frühling Integration TCP-Gateway Bedeutung kann so eingestellt werden, wie folgt:Antwort-Timeout in Integration tcp-Inbound-Gateway im Frühjahr

<!-- Server side --> 

<int-ip:tcp-connection-factory id="crLfServer" 
    type="server" 
    port="${availableServerSocket}"/> 

<int-ip:tcp-inbound-gateway id="gatewayCrLf" 
    connection-factory="crLfServer" 
    request-channel="serverBytes2StringChannel" 
    error-channel="errorChannel" 
    reply-timeout="10000" /> 

<int:channel id="toSA" /> 

<int:service-activator input-channel="toSA" 
    ref="echoService" 
    method="test"/> 

<bean id="echoService" 
    class="org.springframework.integration.samples.tcpclientserver.EchoService" /> 
<int:object-to-string-transformer id="serverBytes2String" 
    input-channel="serverBytes2StringChannel" 
    output-channel="toSA"/> 
<int:transformer id="errorHandler" 
    input-channel="errorChannel" 
    expression="Error processing payload"/> 

Beachten Sie die Antwort-Timeout, die als 10 Sekunden eingestellt wird.

Bedeutet dies, dass der TCP-Server den Dienst anruft und maximal 10 Sekunden warten kann? Wenn der Dienst nicht innerhalb von 10 Sekunden antwortet, sendet der TCP-Server die Nachricht an errorChannel, die wiederum die Client-Fehlermeldung "Fehler bei der Verarbeitung der Nutzdaten" sendet?

Wenn ich den TCP-Server mit einem Dienst getestet habe, der 20 Sekunden dauert, benötigt der Client 20 Sekunden, um die Antwort zu erhalten. Ich sehe keine Fehlermeldung.

Können Sie bitte helfen, das Antwort-Timeout im TCP Inbound-Gateway zu verstehen?

Dank

UPDATE: Vielen Dank für Artem mit diesem Problem zu helfen. Der beste Weg, um dieses Problem zu lösen, ist mit der folgenden Konfiguration:

<beans> 
    <int-ip:tcp-connection-factory id="crLfServer" type="server" port="${availableServerSocket}"/> 
    <int-ip:tcp-inbound-gateway id="gatewayCrLf" connection-factory="crLfServer" request-channel="requestChannel" error-channel="errorChannel" reply-timeout="5000" /> 
    <int:service-activator input-channel="requestChannel" ref="gateway" requires-reply="true"/> 
    <int:gateway id="gateway" default-request-channel="timeoutChannel" default-reply-timeout="5000" /> 
    <int:object-to-string-transformer id="serverBytes2String" input-channel="timeoutChannel" output-channel="serviceChannel"/> 
    <int:channel id="timeoutChannel"> 
     <int:dispatcher task-executor="executor"/> 
    </int:channel> 
    <bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
     <property name="corePoolSize" value="5" /> 
     <property name="maxPoolSize" value="10" /> 
     <property name="queueCapacity" value="25" /> 
    </bean> 
    <int:service-activator input-channel="serviceChannel" ref="echoService" method="test"/> 
    <bean id="echoService" class="org.springframework.integration.samples.tcpclientserver.EchoService" /> 
    <int:transformer id="errorHandler" input-channel="errorChannel" expression="payload.failedMessage.payload + ' errorHandleMsg: may be timeout error'"/> 
</beans> 

Dank

Antwort

1

Nun, eigentlich sollten wir uns auf, dass eine Beschreibung Attribut wie wir in anderen ähnlichen Orten, z.B. HTTP-Eingangs-Gateway:

 <xsd:attribute name="reply-timeout" type="xsd:string"> 
        <xsd:annotation> 
         <xsd:documentation><![CDATA[ 
Used to set the receiveTimeout on the underlying MessagingTemplate instance 
(org.springframework.integration.core.MessagingTemplate) for receiving messages 
from the reply channel. If not specified this property will default to "1000" 
(1 second). 
         ]]></xsd:documentation> 
        </xsd:annotation> 
       </xsd:attribute> 

Diese Zeitüberschreitung gibt an, wie lange auf die Antwort vom Downstream-Datenstrom gewartet werden soll. Aber! Das ist möglich, wenn Sie irgendwo in einen anderen Thread wechseln. Ansonsten wird alles im Thread des Aufrufers ausgeführt und daher ist die Wartezeit nicht deterministisch.

Wie auch immer, wir geben null dort nach Timeout ohne Antwort zurück. Und es ist in der TcpInboundGateway wider:

Message<?> reply = this.sendAndReceiveMessage(message); 
if (reply == null) { 
    if (logger.isDebugEnabled()) { 
     logger.debug("null reply received for " + message + " nothing to send"); 
    } 
    return false; 
} 

Wir haben eine Logik in der TcpInboundGateway für denken können:

if (reply == null && this.errorOnTimeout) { 
    if (object instanceof Message) { 
     error = new MessageTimeoutException((Message<?>) object, "No reply received within timeout"); 
    } 
    else { 
     error = new MessageTimeoutException("No reply received within timeout"); 
    } 
} 

aber scheint für mich ist es wirklich besser wäre, von dem Client auf dem Timeout verlassen .

UPDATE

denke ich, dass wir die Beschränkung überwinden und Sie Anforderungen mit dem midflow treffen <gateway>:

<gateway id="gateway" default-request-channel="timeoutChannel" default-reply-timeout="10000"/> 

<channel id="timeoutChannel"> 
    <dispatcher task-executor="executor"/> 
</channel> 

<service-activator input-channel="requestChannel" 
        ref="gateway" 
        requires-reply="true"/> 

Also, die <service-activator> Anrufe <gateway> und wartet auf die Antwort dort aus. Erfordert die letzte, natürlich, am Ende mit der ReplyRequiredException, die Sie in gewünschte MessageTimeoutException in Ihrem Fehlerfluss auf der error-channel="errorChannel" konvertieren können.

Die timeoutChannel ist ein Vollstrecker ein, unsere default-reply-timeout="10000" sehr nützlich zu machen, weil wir eine Nachricht auf dem Gateway in separaten Thread sofort und nach rechts von dort in Antwort zu warten Prozess eingewickelt mit dem Timeout auf den CountDonwLatch verschieben.

Hoffe, das ist klar.

+0

Ich habe keine Kontrolle über den Client und kann daher keine Logik auf dem Client hinzufügen, um die Zeitüberschreitung zu behandeln. – kevin

+0

Ich schätze Ihre Forschung in der Frage, Artem. Ich habe keine Kontrolle über den Client und kann daher keine Logik auf dem Client hinzufügen, um das Timeout zu verarbeiten. Ich brauche Server, um SocketTimeoutException zu senden oder die Nachricht an error-channel zu senden. Wann geht die Nachricht vom tcp-inbound-Gateway zum Fehlerkanal? Geht die Nachricht in den Fehlerkanal, wenn eine Ausnahme in echoService vorliegt und echoService sie nicht verarbeitet? – kevin

+0

Bitte finden Sie ein Update in meiner Antwort. –