2016-07-25 11 views
0

festgelegt werden Im Grunde ist mir Port zuvor nicht bekannt. Ich werde eine REST-Anforderung an einen Host senden, um die Portnummer zu senden. Ich erhalte die Portnummer, kann aber nicht fortfahren, da ich die Verbindungsfactory nicht in inBoundClient mit der empfangenen Portnummer setzen kann. Bitte sehen Sie sich den folgenden Code an, um das Problem zu verstehen.Wie Port und ConnectionFactory während der Laufzeit für Spring TCP-Integration

Ich habe TCP-Verbindungen wie unten definiert:

<?xml version="1.0" encoding="UTF-8"?> 
<context:component-scan base-package="com.tcpclient" /> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" 
xmlns:int-ip="http://www.springframework.org/schema/integration/ip" 
xmlns:context="http://www.springframework.org/schema/context" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd 
    http://www.springframework.org/schema/integration/ip http://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd"> 
<context:annotation-config /> 
<!--Deserializer for incoming data on the socket --> 
<bean 
class="org.springframework.integration.ip.tcp.serializer.ByteArraySingleTerminatorSerializer" 
id="serializeAndDeserializer"> 
<constructor-arg type="byte" value="0" /> 
</bean> 



<!-- TCP Client configuration --> 

<!-- Channels for communication --> 

<int:channel id="tcp-client-input" /> 

<int:channel id="message" /> 

<int:channel id="message-serviceActivator" /> 

<int:gateway id="gateway" service-interface="com.tcpclient.ClientGateway" 
default-request-channel="tcp-client-input" default-reply-channel="message" /> 



<int-ip:tcp-outbound-channel-adapter 
id="outBoundClient" channel="tcp-client-input" 
retry-interval="60000" auto-startup="false" /> 

<int-ip:tcp-inbound-channel-adapter 
id="inBoundClient" channel="message" 
client-mode="true" auto-startup="false" retry-interval="60000" /> 


<int:object-to-string-transformer 
input-channel="message" output-channel="message-serviceActivator" /> 
<int:service-activator input-channel="message-serviceActivator" 
method="onRtlsMessageArrival"> 
<bean class="com.tcpclient.HandleMessage" /> 
</int:service-activator> 
</beans> 

Config Manager

In meiner Klasse, ich versuche unter:

@component 
public class ConfigManager { 

@Autowired 
@Qualifier("clientFactory") 
TcpConnectionFactoryFactoryBean connFactory; 

@Autowired 
@Qualifier("inBoundClient") 
SmartLifecycle inboundClient; 

@Autowired 
@Qualifier("outBoundClient") 
SmartLifecycle outBoundClient; 

public void initialize(Boolean canStart) { 

try { 
    if (canStart) { 
        String portResponse = restTemplate.postForObject(SYSTEM_OPEN_SOCK_URI, openSockeEntity, 
          String.class); 
        int portNumber = parsePortFromJson(portResponse); 
        connFactory.setPort(portNumber); 
        TcpReceivingChannelAdapter receiver = (TcpReceivingChannelAdapter) inboundClient; 
        receiver.setConnectionFactory(connFactory); 
        receiver.start(); 
        EventDrivenConsumer sender = (EventDrivenConsumer) outBoundClient; 
        sender.start(); 
    } 

} catch (Exception e) { 
    logger.error("Error occured while fetching data."); 
} 
} 
} 

Aber an der Linie receiver.setConnectionFactory(connFactory); , Ich habe Compiler-Fehler, The method setConnectionFactory(AbstractConnectionFactory) in the type TcpReceivingChannelAdapter is not applicable for the arguments (TcpConnectionFactoryFactoryBean). Kann ich den Port trotzdem dynamisch setzen?

EDIT: Wie pro Gary Vorschlag,

@Autowired 
@Qualifier("outboundClient.handler") 
TcpSendingMessageHandler outBoundClient;`, 

outBoundClient.setConnectionFactory(connFactory); 
outBoundClient.setRetryInterval(60000); 
outBoundClient.afterPropertiesSet(); 
outBoundClient.start(); 

Aber, ich habe diesen Fehler unter:

Dispatcher has no subscribers for channel 'application.tcp-client-input'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers

, wenn ich versuche gateway.send("ACK"); eine meiner Bohnen. aber ich habe meine

+0

Natürlich erhalten Sie eine Ausnahme ... Eine 'TcpConnectionFactoryFactoryBean' ist offensichtlich keine' ConnectionFactory'. Es ist ein 'FactoryBean', der eine' ConnectionFactory' erzeugt. –

+0

@ M.Deinum, ja ich stimme dem zu. Es war nur einer der Versuche, die ich gemacht habe. Eigentlich ist es TcpNetClientConnectionFactory. –

Antwort

1

Da der Port in einem Konstruktor festgelegt ist, können Sie es nicht ändern, nachdem die Bean erstellt wurde.

Sie können den Port in einer Connection Factory-Bean auch nicht ändern, nachdem die Verbindungsfactory bereits erstellt wurde.

Sie müssen die Verbindungsfactory selbst erstellen(), anstatt Spring erstellen zu lassen - achten Sie darauf, nach dem Erstellen und Konfigurieren und bevor Sie es dem Adapter hinzufügen, afterPropertiesSet() aufzurufen.

+0

Danke. OK wird das tun und ich werde diese neue Verbindungsfabrik in inBoundClient setzen. Aber, wie wäre es mit OutBoundClient, es ist vom Typ EventDrivenConsumer, ich kann ConnectionFactory hier nicht einstellen. Und mehr noch, ich habe es mit TcpSendingMessageHandler versucht, aber ich kann EventDrivenConsumer nicht auf TcpSendingMessageHandler tippen. –

+0

Verwenden Sie '@Qualifier (" outboundClient.handler ")', um einen Verweis auf den Nachrichtenhandler zu erhalten. –

+0

Ich habe es benutzt, jetzt habe ich ein anderes Problem, was für mich verwirrend ist. Obwohl ich Abonnent habe, klagt es, kein Abonnent gefunden. Ich habe die Frage mit diesen Details bearbeitet. –