私はSSLソケットを作成してクライアントに接続させる必要がある春のブートサーバーアプリケーションを持っています。 私は、クライアントにメッセージを送信することができます(例えば、私のサーバーにREST APIリクエストを送ると)、返信した応答を読むことができます。リクエスト/レスポンスソケットとバネ統合
私はこれまでやって管理することである:
- は、ソケットを作成し、クライアントが接続(およびTcpEventから接続IDを保存)することができ
- 要求に応じてソケットにメッセージを送る
- クライアントが要求を受け取り、バック
このポイント・ツーでは、私は彼らの返事を読み取ることができないんだけど、応答を送信する(と私は、彼らが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());
}
}
}
:ここ
は私のコードです?ありがとうございます。
おかげだから、私の設定が正しいと言うと私は正しく応答を解析していませんよ?それについてのエラーやその他の情報を表示しませんか? –
また、リクエストとレスポンスの両方がJSON形式であり、リクエストを正しく送信できる(つまり、クライアントで受信された)ので、奇妙に思えます。 –
リスナーが適切なパッケージターミネータ。あなたはそれが期待するものをクライアントと相談するべきです。別の考えでは、クライアントがメッセージを受信してソケットを閉じることがあります。私はあなたの設定が正しいかどうかは言えません:私はちょうどそれが部分的に動作するあなたの言葉を信じています。適切なパッケージターミネータは、TCP通信ソリューションの典型的な間違いです。 –