使用@WebListener注解
创建一个监听器继承ServletContextListener类
自动重写ServletContextListener中的contextInitialized(),contextDestroyed()两个方法。
contextInitialized()启动时的方法内容。
contextDestroyed()关闭服务时的方法内容。
代码如下:
import com.xxx.xxx.config.ThreadPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
@Component
@WebListener
@ConfigurationProperties(prefix = "xxxx.udp")
public class HmpsOrionUdpListener implements ServletContextListener {
private static Logger logger = LoggerFactory.getLogger(HmpsOrionUdpListener.class);
private static int udpPort;
private static int maxUdpDataSize;
private ThreadPoolConfig threadPoolConfig = new ThreadPoolConfig();
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
logger.info("========> 启动一个线程,监听UDP数据包,监听端口 {} <======== ", udpPort);
// 启动一个线程,监听UDP数据报
threadPoolConfig.threadPoolTaskExecutor().execute(() -> {
try {
execteUdpMsg(udpPort);
} catch (SocketException e) {
logger.error(e.getMessage());
}
});
}
private void execteUdpMsg(int port) throws SocketException {
//创建服务器端DatagramSocket,指定端口
DatagramSocket socket = new DatagramSocket(port);
logger.info("=======创建数据报,用于接收客户端发送的数据======");
while (true) {
byte[] buffer = new byte[maxUdpDataSize];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
logger.info("=======端口 {} 等待接收消息 ======", udpPort);
socket.receive(packet);
// 接收到的UDP信息,然后解码
buffer = packet.getData();
String srt2 = new String(buffer, StandardCharsets.UTF_8).trim();
logger.info("=======端口 {} 接收接收消息 {} ======", srt2);
} catch (IOException e) {
logger.error(e.getMessage());
}
}
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
logger.info("========> 关闭监听UDP数据包,监听端口 {} <======== ", udpPort);
}
public static int getUdpPort() {
return udpPort;
}
public static void setUdpPort(int udpPort) {
HmpsOrionUdpListener.udpPort = udpPort;
}
public static int getMaxUdpDataSize() {
return maxUdpDataSize;
}
public static void setMaxUdpDataSize(int maxUdpDataSize) {
HmpsOrionUdpListener.maxUdpDataSize = maxUdpDataSize;
}
}
test一下
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class test {
private static final String SERVER_HOSTNAME = "127.0.0.1";
// 服务器端口
private static final int SERVER_PORT = 6007;
// 本地发送端口
private static final int LOCAL_PORT = 8888;
public static void main(String[] args) {
try {
// 1,创建udp服务。通过DatagramSocket对象。
DatagramSocket socket = new DatagramSocket(LOCAL_PORT);
// 2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress
// address, int port)
byte[] buf = "你好,世界".getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName(SERVER_HOSTNAME),
SERVER_PORT);
// 3,通过socket服务,将已有的数据包发送出去。通过send方法。
socket.send(dp);
// 4,关闭资源。
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 线程池配置
*
* @author ruoyi
**/
@Configuration
public class ThreadPoolConfig
{
// 核心线程池大小
private int corePoolSize = 50;
// 最大可创建的线程数
private int maxPoolSize = 200;
// 队列最大长度
private int queueCapacity = 1000;
// 线程池维护线程所允许的空闲时间
private int keepAliveSeconds = 300;
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.initialize();
executor.setMaxPoolSize(maxPoolSize);
executor.setCorePoolSize(corePoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
// 线程池对拒绝任务(无线程可用)的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
xxxx:
udp:
udp_port: 6007
max_udp_data_size: 4096
socket.receive(packet);方法会阻塞
阻塞等待其他socket发从包到本服务器端口,在进行数据的获取