2017-08-30 6 views
0

J'ai une application de disjoncteur de démarrage où j'ai besoin de créer une socket ssl et de laisser un client s'y connecter. Je veux pouvoir envoyer un message au client (lors d'une demande d'API REST à mon serveur par exemple) et aussi lire la réponse qu'il renvoie.Prise de requête/réponse avec intégration de ressort

Ce que je réussi à faire jusqu'à présent est:

  1. Créer la prise et permettre aux clients de se connecter (et enregistrer l'identifiant de connexion du TcpEvent)
  2. Envoyer un message sur la prise sur demande
  3. le client reçoit la demande et renvoie une réponse

dans ce Point- Je ne suis pas en mesure de lire leur réponse (et je ne vois qu'ils envoient une réponse à l'aide Wireshark). même si j'ai configuré un TcpReceivingChannelAdapter qui utilise la même fabrique de connexions que le TcpSendingMessageHandler. À partir de ce moment - je peux envoyer des requêtes mais le client ne les recevra pas ... Je suppose que c'est parce que sa première réponse n'a pas été traitée de mon côté (je n'ai pas accès au code client pour vérifier que).

Voici mon code:

Config.java

@EnableIntegration 
@IntegrationComponentScan 
@Configuration 
public class SocketConfiguration implements ApplicationListener<TcpConnectionEvent> { 

    private static final org.slf4j.Logger log = LoggerFactory.getLogger("SocketConfiguration"); 

    @Bean 
    public AbstractServerConnectionFactory AbstractServerConnectionFactory() { 
     TcpNetServerConnectionFactory tcpNetServerConnectionFactory = new TcpNetServerConnectionFactory(40003); 
     DefaultTcpNetSSLSocketFactorySupport tcpNetSSLSocketFactory = tcpSocketFactorySupport(); 
     tcpNetServerConnectionFactory.setTcpSocketFactorySupport(tcpNetSSLSocketFactory); 
     return tcpNetServerConnectionFactory; 
    } 


    @Bean 
    public DefaultTcpNetSSLSocketFactorySupport tcpSocketFactorySupport() { 
     DefaultTcpSSLContextSupport sslContextSupport = new DefaultTcpSSLContextSupport("keystore.jks", 
      "trustStore.jks", "123456", "123456"); 
     sslContextSupport.setProtocol("TLSv1.2"); 
     DefaultTcpNetSSLSocketFactorySupport tcpSocketFactorySupport = new DefaultTcpNetSSLSocketFactorySupport(sslContextSupport); 
     return tcpSocketFactorySupport; 
    } 

    @Bean 
    public static MessageChannel getResponseChannel() { 
     DirectChannel directChannel = new DirectChannel(); 
     directChannel.setComponentName("getResponseChannel"); 
     directChannel.setLoggingEnabled(true); 
     return directChannel; 
    } 

    @Bean 
    public static MessageChannel getInputMessageChannel() { 
     DirectChannel directChannel = new DirectChannel(); 
     directChannel.setComponentName("inputMessageChannel"); 
     directChannel.setLoggingEnabled(true); 
     return directChannel; 
    } 

    @Bean 
    public MessageChannel invokeChannel() { 
     return new DirectChannel(); 
    } 

    @Bean 
    public TcpReceivingChannelAdapter in(AbstractServerConnectionFactory connectionFactory) { 
     TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter(); 
     adapter.setOutputChannel(getInputMessageChannel()); 
     adapter.setConnectionFactory(connectionFactory); 
     adapter.setSendTimeout(5000); 
     return adapter; 
    } 

    @ServiceActivator(inputChannel="toClientChannel") 
    @Bean 
    public TcpSendingMessageHandler out(AbstractServerConnectionFactory connectionFactory) { 
     TcpSendingMessageHandler tcpSendingMessageHandler = new TcpSendingMessageHandler(); 
     tcpSendingMessageHandler.setConnectionFactory(connectionFactory); 
     tcpSendingMessageHandler.setLoggingEnabled(true); 
     return tcpSendingMessageHandler; 
    } 

    @Transformer(inputChannel = "invokeChannel", outputChannel = "toClientChannel") 
    public Message<String> headerBeforeSend(String message) throws Exception { 
     log.debug("send message to socket: {}", message); 
     Map.Entry<String, TcpConnection> connectionEntry = GetConnectionEntry(); 
     log.debug("connection id is: {}", connectionEntry.getKey()); 
     return MessageBuilder.withPayload(message) 
     .setHeader(IpHeaders.CONNECTION_ID,connectionEntry.getKey()) 
     .build(); 
    } 

    private static ConcurrentHashMap<String, TcpConnection> tcpConnections = new ConcurrentHashMap<>(); 

    @Override 
    public void onApplicationEvent(TcpConnectionEvent tcpEvent) { 
     TcpConnection source = (TcpConnection) tcpEvent.getSource(); 
     if (tcpEvent instanceof TcpConnectionOpenEvent) { 
     log.info("Socket Opened " + source.getConnectionId()); 
     tcpConnections.put(tcpEvent.getConnectionId(), source); 
     } else if (tcpEvent instanceof TcpConnectionCloseEvent) { 
     log.info("Socket Closed " + source.getConnectionId()); 
     if(tcpConnections.containsKey(source.getConnectionId())) 
      tcpConnections.remove(source.getConnectionId()); 
     } else if (tcpEvent instanceof TcpConnectionExceptionEvent) { 
     log.error("Error {}",tcpEvent.getCause().getMessage()); 
     if(tcpConnections.containsKey(source.getConnectionId())) 
      tcpConnections.remove(source.getConnectionId()); 
     } 
    } 
} 

Controller.java

@RestController 
@ControllerAdvice 
@RequestMapping("/socket") 
public class SocketController { 
    private final Logger log = LoggerFactory.getLogger(getClass()); 

    @Inject 
    MessageChannel invokeChannel; 

    @LogAspect 
    @PostMapping 
    public ResponseEntity sendMessage(@RequestBody SendMessageRequest request) throws Exception { 
     log.debug("Message is {}",request.get_message()); 
     String msg = "Some test message"; 
     MessagingTemplate template = new MessagingTemplate(); 
     template.send(invokeChannel, new GenericMessage<>(msg)); 
     return new ResponseEntity(HttpStatus.OK); 
    } 
} 

Pouvez-vous s'il vous plaît vérifier ma configuration et me diriger vers la bonne configuration ?

Merci

Répondre

0

Vous devez être sûr que vous envoyez et recevez des messages correctement sérialisés et désérialisés. Par défaut, il est ByteArrayCrlfSerializer qui est basé sur la terminaison de message \r\n: https://docs.spring.io/spring-integration/docs/4.3.11.RELEASE/reference/html/ip.html#connection-factories

+0

Merci pour le relpy Vous dites que ma configuration est juste et je ne suis pas correctement la réponse de l'analyse? cela ne montrerait-il pas une erreur à ce sujet ou d'autres informations? –

+0

Aussi il semble étrange que ma demande et la réponse sont au format JSON et je suis en mesure d'envoyer ma demande correctement (c'est-à-dire qu'il est reçu dans le client) –

+0

Nous ne voyons pas d'erreurs parce que votre auditeur peut attendre le terminateur de paquet approprié. Vous devriez consulter le client à quoi s'attendre. Un autre a pensé que votre client pourrait recevoir un message et fermer le socket. Je ne peux pas dire si votre config est correcte ou non: je crois juste vos mots que cela fonctionne partiellement. Un terminateur de paquet non approprié est une erreur typique dans une solution de communication TCP –