2016-10-17 4 views
0

tcp-inbound gateway가 사용하는 포트를 변경하는 방법이 있습니까? tcp-inbound-gateway가 사용하는 포트 및 타임 아웃을 데이터베이스에 유지되는 구성을 기반으로 설정하고 응용 프로그램을 다시 시작하지 않고 즉시 변경할 수있는 기능을 설정하고 싶습니다.즉석에서 tcp-ibound-gateway가 사용하는 포트를 변경하는 방법

public class RuntimeInboundGateway extends TcpInboundGateway implements SettingsSubscriber { 

    @Autowired 
    private Settings settings; 

    @PostConstruct 
    public void subscribe() { 
     settings.subscribe(this); 
    } 

    @Override 
    public void onSettingsChanged(Settings settings) { 
     this.stop(); 
     AbstractByteArraySerializer serializer = new ByteArrayLfSerializer(); 
     TcpNetServerConnectionFactory connectionFactory = new TcpNetServerConnectionFactory(settings.getPort()); 
     connectionFactory.setSerializer(serializer); 
     connectionFactory.afterPropertiesSet(); 
     this.setConnectionFactory(connectionFactory); 
     this.afterPropertiesSet(); 
     this.start(); 
    } 
} 

settings 객체가 싱글 콩과는 TCP를 변경할 때 수신 게이트웨이는 새로운 포트에서 수신 참으로 시작합니다이를 위해 나는 "게시 가입자를"패턴과 확장 TcpInboundGateway 클래스를 사용하기로 결정 그러나 흐름에서 인바운드 메시지를 더 보내지 않는 것처럼 보입니다. 다음은 XML 구성에서 발췌 한 것입니다 :

<int-ip:tcp-connection-factory id="connFactory" type="server" port="${port}" 
            serializer="serializer" 
            deserializer="serializer"/> 

    <bean id="serializer" class="org.springframework.integration.ip.tcp.serializer.ByteArrayLfSerializer"/> 

    <bean id="inboundGateway" class="com.example.RuntimeInboundGateway"> 
     <property name="connectionFactory" ref="connFactory"/> 
     <property name="requestChannel" ref="requestChannel"/> 
     <property name="replyChannel" ref="responseChannel"/> 
     <property name="errorChannel" ref="exceptionChannel"/> 
     <property name="autoStartup" value="true"/> 
    </bean> 

설정이 변경 될 때까지 문제없이 서비스에 대한 모든 요청을 기록 구성에 로그인 채널 어댑터가 있습니다. 그 후, 그것은하지 않으며 새 포트에 telnet localhost <NEW_PORT>에 연결할 수 있지만받은 메시지가 표시되지 않습니다. 누군가가 한 번 봐서 원하는 행동이 어떻게 성취 될 수 있는지 말할 수 있습니까?

답변

0

문제의 원인은 저입니다. 디시리얼라이저는 위 코드에서 지정되지 않았기 때문에 기본값이 사용되며 입력 바이트 스트림에서 인바운드 메시지를 구별 할 수 없습니다. 한 줄의 connectionFactory.setDeserializer(serializer);은 하루를 보냈다.

0

는 코드에서 빠른보기는

@SpringBootApplication 
public class So40084223Application { 

    public static void main(String[] args) throws Exception { 
     ConfigurableApplicationContext ctx = SpringApplication.run(So40084223Application.class, args); 
     Socket socket = SocketFactory.getDefault().createSocket("localhost", 1234); 
     socket.getOutputStream().write("foo\r\n".getBytes()); 
     socket.close(); 
     QueueChannel queue = ctx.getBean("queue", QueueChannel.class); 
     System.out.println(queue.receive(10000)); 
     ctx.getBean(MyInboundGateway.class).recycle(1235); 
     socket = SocketFactory.getDefault().createSocket("localhost", 1235); 
     socket.getOutputStream().write("fooo\r\n".getBytes()); 
     socket.close(); 
     System.out.println(queue.receive(10000)); 
     ctx.close(); 
    } 

    @Bean 
    public TcpNetServerConnectionFactory cf() { 
     return new TcpNetServerConnectionFactory(1234); 
    } 

    @Bean 
    public MyInboundGateway gate(TcpNetServerConnectionFactory cf) { 
     MyInboundGateway gate = new MyInboundGateway(); 
     gate.setConnectionFactory(cf); 
     gate.setRequestChannel(queue()); 
     return gate; 
    } 

    @Bean 
    public QueueChannel queue() { 
     return new QueueChannel(); 
    } 

    public static class MyInboundGateway extends TcpInboundGateway implements ApplicationEventPublisherAware { 

     private ApplicationEventPublisher applicationEventPublisher; 

     @Override 
     public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { 
      this.applicationEventPublisher = applicationEventPublisher; 
     } 

     public void recycle(int port) { 
      stop(); 
      TcpNetServerConnectionFactory sf = new TcpNetServerConnectionFactory(port); 
      sf.setApplicationEventPublisher(this.applicationEventPublisher); 
      sf.afterPropertiesSet(); 
      setConnectionFactory(sf); 
      afterPropertiesSet(); 
      start(); 
     } 

    } 

} 

내가 있는지 확인하기 위해 디버그 로깅을 설정 것이다 ... 나는 그냥 빨리 봄 부팅 응용 프로그램을 작성하고 나를 위해 잘 작동 그래서, 확인 작업을해야 표시 그것은 당신에게 어떤 단서를줍니다.

새로운 DSL dynamic flow registration을 대신 사용해보세요. tcp-dynamic-client은 해당 기술을 사용하여 흐름 스 니펫을 즉시 추가/제거하는 방법을 보여줍니다. 그것은 클라이언트 측에 있지만 게이트웨이와 연결 팩토리를 등록/등록 해제하기 위해 비슷한 기술을 서버 측에서 사용할 수 있습니다.

+0

안녕하세요 @ 게리 러셀, 내 수치에 대한 문제의 원인은 나입니다. 우리는'ByteArrayLfSerializer'를 serialize와 deserialize 메시지에 사용합니다. 그래서 디폴트 deserializer를 사용하여 코드에서 deserializer를 설정하지 않았습니다. 방해해서 죄송합니다. 위의 코드 스 니펫이 향후 누군가에게 도움이되기를 바랍니다. – user6231016

+0

TCP 이벤트를 수신하려면 비 Spring 관리 연결 팩토리에 이벤트 게시자를 삽입해야합니다. –

+0

게리, 나는 얼마 동안 스프링 통합과 관련하여 일 해왔고, 스프링 통합을 사용하는 사람들이 인내심을 가지고 답을 찾고 문제를 해결하는 데 도움을주기 위해 많은 노력을 기울였습니다. 당신의 도움이 크게 감사한다고 말하고 지원하십시오. – user6231016

관련 문제