2017-08-30 4 views
0

私はSSLソケットを作成してクライアントに接続させる必要がある春のブートサーバーアプリケーションを持っています。 私は、クライアントにメッセージを送信することができます(例えば、私のサーバーにREST APIリクエストを送ると)、返信した応答を読むことができます。リクエスト/レスポンスソケットとバネ統合

私はこれまでやって管理することである:

  1. は、ソケットを作成し、クライアントが接続(およびTcpEventから接続IDを保存)することができ
  2. 要求に応じてソケットにメッセージを送る
  3. クライアントが要求を受け取り、バック

このポイント・ツーでは、私は彼らの返事を読み取ることができないんだけど、応答を送信する(と私は、彼らがWiresharkのを使用して返信していることがわかります)。 TcpSendingMessageHandlerと同じ接続ファクトリを使用するTcpReceivingChannelAdapterを設定しましたが、

その時点以降、私はリクエストを送信することができますが、クライアントはそれらを受け取ることはできません...自分の最初のレスポンスが私の側で処理されなかったからです(私はクライアントコードにアクセスできませんそれを確認する)。あなたは私の設定をチェックし、右のセットアップに私を指示してくださいすることができ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); 
    } 
} 

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()); 
     } 
    } 
} 

:ここ

は私のコードです?

ありがとうございます。

答えて

0

正しく送受信されたメッセージを送受信するようにしてください。デフォルトでは、\r\nメッセージターミネータに基づいていますByteArrayCrlfSerializerです:relpy ためhttps://docs.spring.io/spring-integration/docs/4.3.11.RELEASE/reference/html/ip.html#connection-factories

+0

おかげだから、私の設定が正しいと言うと私は正しく応答を解析していませんよ?それについてのエラーやその他の情報を表示しませんか? –

+0

また、リクエストとレスポンスの両方がJSON形式であり、リクエストを正しく送信できる(つまり、クライアントで受信された)ので、奇妙に思えます。 –

+0

リスナーが適切なパッケージターミネータ。あなたはそれが期待するものをクライアントと相談するべきです。別の考えでは、クライアントがメッセージを受信して​​ソケットを閉じることがあります。私はあなたの設定が正しいかどうかは言えません:私はちょうどそれが部分的に動作するあなたの言葉を信じています。適切なパッケージターミネータは、TCP通信ソリューションの典型的な間違いです。 –

関連する問題