Spring Integration - 线程出站频道

时间:2017-10-24 18:43:54

标签: java spring spring-integration

提前致谢!我正在进行一个简单的TCP集成,其目标是让许多客户端连接到服务器并促进客户端和服务器之间的异步消息。我已经将示例中的一些代码拼凑在一起,除了一件事之外,一切都按预期工作:

当一个连接停止(不断开连接,但执行类似丢弃所有数据包之类的操作)时,所有其他连接将停止接收消息,直到恢复为止。为了与客户进行通信,我应该实施或改变什么,而不是与其他客户的连接困境?

服务器配置如下:

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.ExecutorChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.TcpSendingMessageHandler;
import org.springframework.integration.ip.tcp.connection.*;
import org.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer;
import org.springframework.integration.ip.tcp.serializer.ByteArrayLfSerializer;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.scheduling.TaskScheduler;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;



@EnableIntegration
@Configuration
public class IntegrationConfig {
    private static final Logger log = Logger.getLogger(IntegrationConfig.class);

    @Value("${listen.port:8000}")
    private int port;

    @Autowired
    Relayer relayer;

    @Bean  //for accepting text message from TCP, putty
    public MessageChannel fromTcp() {
        return new ExecutorChannel(threadPoolTaskExecutor());
    }

    @Bean  //inbound, it is working, I could read the inbound message while debugging
    public TcpReceivingChannelAdapter in(
            AbstractServerConnectionFactory connectionFactory) {
        TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
        adapter.setOutputChannel(fromTcp());
        adapter.setConnectionFactory(connectionFactory);

        return adapter;
    }
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(100);
        return taskScheduler;
    }

    @Bean
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setMaxPoolSize(100);
        threadPoolTaskExecutor.setCorePoolSize(100);
        return threadPoolTaskExecutor;
    }

    @Bean
    public MessageChannel toTcp() {
        ExecutorChannel directChannel = new ExecutorChannel(threadPoolTaskExecutor());
        relayer.setOutboundChannel(directChannel);
        return directChannel;
    }

    @ServiceActivator(inputChannel = "toTcp")
    @Bean
    public TcpSendingMessageHandler out(
            AbstractServerConnectionFactory connectionFactory) {
        TcpSendingMessageHandler tcpOutboundAdp = new TcpSendingMessageHandler();
        tcpOutboundAdp.setConnectionFactory(connectionFactory);
        return tcpOutboundAdp;
    }

    @ServiceActivator(inputChannel = "fromTcp")
    public void handleIncompingMessage(Message<byte[]> stringMsg) {
        String new_message = new String(stringMsg.getPayload());
        new_message = new_message.replaceAll("\r", "");
        new_message = new_message.replaceAll("\n", "");
        relayer.processIncomingMessage((String) stringMsg.getHeaders().get("ip_connectionId"), new_message);
    }

    @Bean
    public AbstractServerConnectionFactory serverCF() {
        TcpNetServerConnectionFactory tcpNetServerConnectionFactory = new TcpNetServerConnectionFactory(this.port);
        tcpNetServerConnectionFactory.setSingleUse(false);
        tcpNetServerConnectionFactory.setSerializer(new ByteArrayCrLfSerializer());
        tcpNetServerConnectionFactory.setDeserializer(new ByteArrayLfSerializer());
        return tcpNetServerConnectionFactory;
    }
    @EventListener
    public void onApplicationEvent(TcpConnectionOpenEvent event) {
        relayer.newConnection(event.getConnectionId());
    }

    @EventListener
    public void onApplicationEvent(TcpConnectionCloseEvent event) {
        relayer.deleteConnection(event.getConnectionId());
    }
}

这是基于许多例子,而且除了一个客户端滞后之外,它都有效。我的应用程序的其他部分与输出通道对话,我应该在中间有某种聚合器吗?

干杯!

1 个答案:

答案 0 :(得分:1)

有些东西没有加起来;尝试将数据发送到套接字时阻止 <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script> <table id="data-table"> <thead> <tr> <th class="col-lg-3 tablehead">Item Number</th> <th class="col-lg-3 tablehead">Description</th> <th class="col-lg-3 tablehead">Quantity</th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td class="col-lg-3 tabledata">@item.itemNumber</td> <td class="col-lg-3 tabledata">@item.description</td> <td class="col-lg-3 tabledata">@item.quantity</td> </tr> } </tbody> </table> <script type="text/javascript"> $(document).ready(function () { $('#data-table').DataTable(); }); </script> ;连接对象被锁定...

import csv
import xlrd

file_location = "C:/Users/Sean/Desktop/DADSA 17-18 COURSEWORK A MALE PLAYERS.csv"

if file_location.endswith(".csv"):
    with open(file_location) as fp:
        for row in csv.reader(fp):
            # do something with rows
elif file_location.endswith((".xls", ".xlsx")):
    workbook = xlrd.open_workbook(file_location)
    # do something with workbook

其他9个线程正在等待获取该锁(threadPoolTaskExecutor-9- locked <0x0000000746902810> (a org.springframework.integration.ip.tcp.connection.TcpNetConnection) ),因此您似乎正在尝试同时向同一个套接字写入多条消息。

所以发送到其他套接字不是问题,发送到一个套接字的问题(可能是因为它的缓冲区已满)。

修改

这是在每个套接字的单个线程上执行所有出站发送的一种方法...

send()

结果:

synchronized