如何在Spring-Boot中使用@ServiceActivator处理多行字符串消息

时间:2019-02-14 21:54:51

标签: spring-boot tcpserver multilinestring

我正在构建一个spring-boot应用程序,以处理来自通过TCP连接发送的日志记录设备的消息。我找到了一种处理单行消息的绝妙解决方案,但是我正努力使其与设备发送的三行消息一起使用。

我尝试使用@ Aggregator,@ ReleaseStrategy和@AggregationStrategy来累积来自同一ip的消息,但是@ServiceActivator仍然只显示一行。

@Aggregator
public List<String> aggregatingMethod(Message<?> message) {
    List<String> result = new ArrayList<>();
    String line = message.getPayload().toString();
    result.add(line);
    return result;
}

@ReleaseStrategy
public boolean releaseChecker(List<String> messages) {
  return messages.size() == 3;
}

@CorrelationStrategy
public String correlateBy(Message<?> message) {
  return message.getHeaders().get("ip_address").toString();
}

@ServiceActivator(inputChannel = "serviceChannel")
public void service(List<String> in) {
    System.out.println("Message");
    for(String line: in){           
        System.out.println(line.toString());
    }       
    String clientData = in.get(0) + in.get(1);
if (clientData != null && !clientData.isEmpty() && clientData.length() 
        > 30 && clientData.charAt(0) == '#') {
    // send the message to RabbitMQ
    log.info("Received <" + clientData + ">");
    messageService.sendMessage(clientData);
    log.info("Added to the queue " + 
        SpringBootRabbitMQApplication.ELD_MESSAGE_QUEUE);
} else {
    log.error("Message is null or in wrong format format: " + 
        clientData);
    // reader.close();
}
}

这是我发现的单行消息示例     包com.example;

import java.net.Socket;

import javax.net.SocketFactory;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.transformer.ObjectToStringTransformer;
import org.springframework.messaging.MessageChannel;

@SpringBootApplication
public class So39290834Application {

public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext context = SpringApplication.run(So39290834Application.class, args);
    Socket socket = SocketFactory.getDefault().createSocket("localhost", 9999);
    socket.getOutputStream().write("foo\r\n".getBytes());
    socket.close();
    Thread.sleep(1000);
    context.close();
}

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

@Bean
public TcpReceivingChannelAdapter inbound(AbstractServerConnectionFactory cf) {
    TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
    adapter.setConnectionFactory(cf);
    adapter.setOutputChannel(tcpIn());
    return adapter;
}

@Bean
public MessageChannel tcpIn() {
    return new DirectChannel();
}

@Transformer(inputChannel = "tcpIn", outputChannel = "serviceChannel")
@Bean
public ObjectToStringTransformer transformer() {
    return new ObjectToStringTransformer();
}

@ServiceActivator(inputChannel = "serviceChannel")
public void service(String in) {
    System.out.println(in);
}

}

我现在正在使用ThreadPoolExecutor并以老式方式处理tcp连接:

public static void main(String[] args) throws IOException {
    SpringApplication.run(SpringBootRabbitMQApplication.class, args);
    // create the socket server object
    server = new ServerSocket(port);

    while (true) {
        try {
            // socket object to receive incoming client requests
            final Socket s = server.accept();
            taskExecutor.execute(new Runnable(){

                @Override
                public void run() {
                    boolean messageIsValid = true;
                    while (messageIsValid) {
                        try {
                            // obtaining input and out streams
                            BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));

                            String clientData = "";
                            // read message string
                            clientData = reader.readLine();
                            clientData += reader.readLine();
                            reader.readLine();
                            log.info("Read message from port: " + clientData);

                            if (clientData != null && !clientData.isEmpty() && clientData.length() > 30
                                    && clientData.charAt(0) == '#') {
                                // send the message to RabbitMQ
                                messageService.sendMessage(clientData);
                            } else {
                                log.error("Message is null or in wrong format format: " + clientData + "; Client address: " + s.getInetAddress());
                                messageIsValid = false;
                            }
                        } catch (IOException e) {
                            log.error("Couldn't read the message from socket");
                            e.printStackTrace();
                            messageIsValid = false;
                        }
                    }                       
                }                   
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

它可以按预期工作,但是我想使用@ServiceActivator使其工作。

0 个答案:

没有答案