2017-09-12 4 views
0

Je suis donc en train d'encapsuler le client Spring Integration TCP pour fournir des API pour mon application. Les questions précédentes à ce sujet peuvent être trouvées here et here. Le problème avec ceci est que le gateway.send() ne se termine pas du tout et la réponse de l'API ne revient jamais.Implémentation Spring TCP Socket Integration ne passant pas la méthode gateway.send

Voici mon fichier ServerConnection.java:

package com.abc.xyz.serverconnection; 
import org.springframework.context.support.GenericXmlApplicationContext; 
public class ServerConnections {  
    private SimpleGateway gateway;  
    public ServerConnections() { 
     final GenericXmlApplicationContext context = setupContext(); 
     this.setGateway(context.getBean(SimpleGateway.class)); 
    }  
    public static GenericXmlApplicationContext setupContext() { 
     final GenericXmlApplicationContext context = new GenericXmlApplicationContext(); 
     context.load("classpath:META-INF/spring/integration/tcpClientServerDemo-context.xml"); 
     context.registerShutdownHook(); 
     context.refresh(); 
     return context; 
    }  
    public SimpleGateway getGateway() { 
     return gateway; 
    }  
    public void setGateway(SimpleGateway gateway) { 
     this.gateway = gateway; 
    }  
    public boolean sendData(String input) { 
     this.gateway.send(input); 
     return true; 
    }  
    public void recieveData(String output) { 
     System.out.println("Data from server:" + output); 
    }  
} 

Dans mon contrôleur, je fais quelque chose comme ceci:

@RequestMapping(value = "/logon", method = RequestMethod.GET) 
@ResponseBody 
public String logon() { 
    // logics go here and the result is stored like below and sent 
    String message = "0000005401F40000C1E3E304010000000020000000000000000000000000000000000000000000004040404040404040C1E3E300C1C2C3C4C5C6C7C8E8C5E2C8E6C1D540F1F7F24BF0F1F64BF0F0F34BF0F5F200"; 
    if (serverConnections.sendData(message)) { 
     return "Data sent successfully!"; 
    } else { 
     return "Data not sent!"; 
    } 
} 

Voici comment ma config ressemble:

<context:property-placeholder /> 
    <int:channel id="input" /> 
    <int:channel id="toSA" /> 
    <int:service-activator input-channel="toSA" 
          ref="echoService" 
          method="recieveData"/> 
    <bean id="echoService" class="com.abc.xyz.serverconnection.ServerConnection" /> 
    <bean id="CustomSerializerDeserializer" class="com.abc.xyz.serverconnection.CustomSerializerDeserializer" /> 
    <int:object-to-string-transformer id="serverBytes2String" 
             input-channel="serverBytes2StringChannel" 
             output-channel="toSA"/> 
    <int:gateway id="gw" 
       service-interface="com.abc.xyz.serverconnection.SimpleGateway" 
       default-request-channel="input"/> 
    <int-ip:tcp-connection-factory id="client" 
            type="client" 
            host="<ip>" 
            serializer="CustomSerializerDeserializer" 
            deserializer="CustomSerializerDeserializer" 
            port="6100" 
            single-use="false" /> 
    <int-ip:tcp-outbound-gateway id="outGateway" 
           request-channel="input" 
           reply-channel="serverBytes2StringChannel" 
           connection-factory="client" /> 

EDIT : Impossible d'obtenir le journal DEBUG de l'application car j'utilise l'implémentation du client TCP en tant que Ma ven Module dans un projet Maven. Un autre module utilise cela comme une dépendance et c'est là que résident les points d'extrémité de l'API REST.

Répondre

3

Je pense que votre

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

ne renvoie aucun résultat à envoyer à l'en-tête replyChannel, quant à lui votre gateway.send() est pas une méthode void. C'est ainsi qu'il attend la réponse qui ne revient jamais.

+0

La passerelle sortante TCP expirera au bout de 5 secondes et le thread restera dans la passerelle en attente d'une réponse qui ne viendra jamais. Définissez 'default-reply-timeout' sur' gw' à 5000 pour correspondre. Si vous ne voulez pas attendre une réponse, changez la méthode pour retourner 'void' ou mettez' default-reply-timeout' à 0. Comme @artem l'a dit, vous devriez vraiment utiliser un adaptateur de canal pour les opérations d'envoi seulement . –

+0

@artem @gary merci pour vos entrées. J'ai changé la passerelle pour retourner 'void'. Cela fonctionne mais je voudrais comprendre le point de @ artem. Mon 'EchoService' renvoie un' void' mais 'gateway.send()' renvoie une chaîne. Cela signifie-t-il que j'ai besoin d'attraper la réponse 'gateway.send()' quelque part? Je ne comprends pas le point. – JackSlayer94

+0

'EchoService' renvoyer' void' semble pour moi un oxymore :) (Je me rends compte que vous avez obtenu le nom de l'échantillon). Une méthode de passerelle qui renvoie non-void indique au framework qu'une réponse est attendue; lorsque le thread retourne à la passerelle, il attend cette réponse. Il y a un timeout, mais par défaut c'est l'infini. Puisque vous renvoyez void de votre service, le flux se termine à ce moment-là, et la réponse n'arrivera jamais. Une méthode de passerelle qui renvoie 'void' indique au framework qu'aucune réponse ne viendra jamais. Pour les messages de demande/réponse, il est généralement préférable de bloquer le thread appelant jusqu'à l'arrivée de la réponse. –