【问题标题】:How to create an asynchronous singleton socket server with spring-integration?如何使用弹簧集成创建异步单例套接字服务器?
【发布时间】:2018-11-22 20:00:03
【问题描述】:

我想使用spring-integration 实现以下目标:拥有一个不断接收和写入数据的单例打开套接字,asyncrhon!

这意味着我必须打开一个不断从单个套接字读取的套接字,调度每个消息以进行异步处理,并通过套接字返回也异步的响应。

我怎样才能实现这种异步模式?

特别是:我如何使用Serializer/Deserializer?据我了解,仅在 new 套接字连接上调用序列化程序,所以在我的情况下,仅在第一条消息开始时调用一次?

@Configuration
public class SocketConfig {
    @Bean
    public TcpConnectionFactoryFactoryBean tcpFactory(MyConverter converter) {
        TcpConnectionFactoryFactoryBean fact = new TcpConnectionFactoryFactoryBean();
        fact.setType("server");
        fact.setPort(PORT);
        fact.setUsingNio(true); //should I use true or false?
        fact.setSingleUse(false); //keep socket constantly open
        fact.setSerializer(converter);
        fact.setDeserializer(converter);
        return fact;
    }

    @Bean
    public TcpInboundGateway serverGateway(
            @Qualifier("tcpFactory") TcpConnectionFactoryFactoryBean factory,
            @Qualifier("serverChannel") MessageChannel serverChannel) throws Exception {
        TcpInboundGateway g = new TcpInboundGateway();
        g.setConnectionFactory(factory.getObject());
        g.setRequestChannel(serverChannel);
        return g;
    }

}

@MessageEndpoint
public class SocketEndpoint {

    @ServiceActivator(inputChannel = "serverChannel")
    public Object run(Object obj) {

    }
}


@Service
public class MyConverter implements Serializer<Object>, Deserializer<Object> {
    //read from socket
    @Override
    public Object deserialize(InputStream inputStream) {
    }

    //send back to socket
    @Override
    public void serialize(Object message, OutputStream outputStream) {
    }
}

【问题讨论】:

    标签: java spring sockets spring-integration


    【解决方案1】:

    网关用于单个请求/响应对。

    如果您需要为单个请求发送多个响应,则必须使用collaborating channel adapters as described in the documentation

    协作适配器也可用于(服务器端或客户端)完全异步通信(而不是请求/回复语义)。

    在服务器端,必须小心填充 ip_connectionId 标头,因为它用于将消息与连接相关联。源自入站适配器的消息将自动设置标头。如果您希望构建其他要发送的消息,则需要设置标头。可以从传入的消息中捕获标头值。

    【讨论】:

    • 我只想为每个请求发送一个响应。唯一的事情是套接字保持永久打开。意味着必须不断地通过套接字读取和写入消息,所有这些都是异步的。
    • 我对“分割消息”感到困惑——这暗示我你的意思是每条消息都被分割了,但我现在明白你的意思了;那应该行得通;该框架正是为此目的提供了ByteArrayLengthHeaderSerializer。如果它不适合您,请编辑问题以准确解释问题所在。使用 NIO 意味着您将自动获得多线程。
    • 您将返回每条消息;将调用deserialize() 方法来获取下一条消息。有关示例,请参见 ByteArrayLengthHeaderSerializer
    • 否;他们可以阻止。发送操作是同步的,因此一次只能发生一个写操作,从而防止数据交错。在接收端你不能有“并发反序列化”;这没有道理;反序列化程序仅应在消息完全解码后退出。当 NIO 为 true 并且存在更多数据时,下一个反序列化被分派到另一个线程。如果为 false,则单个线程会执行所有读取操作,如果您想在处理当前消息时读取下一条消息,则可以使用执行器通道。
    • 我对其进行了编辑以阐明网关的使用。协作适配器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 2013-11-10
    相关资源
    最近更新 更多