当前位置: 首页 > 知识库问答 >
问题:

如何动态更改tcp ibound网关使用的端口

耿联
2023-03-14

有没有办法动态更改tcp-inbing-网关使用的端口?我想根据数据库中持久化的配置设置tcp-inbing-网关使用的端口和超时,并且能够在不重新启动应用程序的情况下动态更改它们。为了做到这一点,我决定使用“发布-订阅者”模式和扩展的TcpInoundGateway类:

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

设置对象是一个单例bean,当它被更改时,tcp入站网关确实开始侦听新端口,但看起来它不会在流中进一步发送入站消息。以下是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本地主机连接到新端口


共有2个答案

储毅
2023-03-14
匿名用户

问题的原因是我。因为上面的代码中没有指定反序列化程序,所以使用了默认的反序列化程序并且它无法从输入字节流中划分入站消息。只有一行<code>connectionFactory。setDeserializer(序列化器)解决了我花了一天时间解决的问题。

扶高歌
2023-03-14

快速查看您的代码表明它应该可以正常工作,所以我刚刚编写了一个快速的Spring Boot应用程序,它对我来说效果很好……

@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动态流注册。tcp-Dynamic-client展示了如何使用该技术即时添加/删除流片段。它在客户端,但在服务器端可以使用类似的技术来注册/取消注册您的网关和连接工厂

 类似资料:
  • 问题内容: 我有一个网页,该网页实现了一组标签,每个标签显示不同的内容。选项卡单击不会刷新页面,而是在客户端隐藏/取消隐藏内容。 现在,需要根据页面上选择的选项卡来更改页面标题(出于SEO的原因)。这可能吗?有人可以提出一种解决方案,以通过javascript动态更改页面标题而无需重新加载页面吗? 问题答案: 更新 :根据SearchEngineL上的注释和参考,大多数网络爬虫将为更新的标题编制索

  • 我有以下元素,我想单击每个选项卡并检查输入字段中是否存在值,我想避免为每种语言创建每个WebElement 谁能告诉我怎么办。否则,我会为每种语言安装元素,并单击并检查文本区域,因此如果可以操纵xpath或css,那就太棒了 提前非常感谢各位。

  • 问题内容: 我需要动态添加组件。此外,我需要动态更改布局。 问题答案: 作为参考,以下是显示基本方法的脚本validate()。这个更精致的示例显示了两个要求:它更改布局并动态添加组件。

  • 问题内容: 简而言之,有一个简单的java swing应用程序,其中包含JFrame和其中的某些组件。组件之一是一个JPanel,可以根据用户操作将其替换为另一个JPanel。 那么,做这种事情的正确方法是什么?我试过了 但这行不通。你有什么建议? 问题答案: 你的用例对于CardLayout来说似乎很完美。 在卡片布局中,你可以在同一位置添加多个面板,但是一次只能显示或隐藏一个面板。

  • 现在,我有一个简单的Spring Boot应用程序,它为静态图像提供服务,我将这些图像放在了resources/static/img中。这对于显示实际内容来说很好,但我想解决两件事: > 我不希望这些图像中的任何一个与生成的文件捆绑在一起,我知道将这些图像放在文件夹中会做到这一点。 使用我当前的设置,为了在webapp上看到新图像,我必须将其添加到文件夹并重新启动。相反,我希望Spring提供特定

  • 问题内容: 我有以下几点: 我正在尝试对结构进行json编码,但是在我需要更改json键之前,例如,最终的json应该如下所示: 我注意到value.Type()。Field(i).Tag.Get(“ json”)的方法,但是没有设置方法。为什么?以及如何获取所需的json输出。 另外,如何遍历所有字段,包括嵌入式结构Another? https://play.golang.org/p/Qi8Jq