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:
- Créer la prise et permettre aux clients de se connecter (et enregistrer l'identifiant de connexion du TcpEvent)
- Envoyer un message sur la prise sur demande
- 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
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? –
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) –
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 –