yeg
2026-08-27 a4f06a9095a2eab0bb48b406c4609be6e70b8854
ruoyi-device/src/main/java/com/ruoyi/device/bts/ScriptedBtsTcpSimulator.java
@@ -2,6 +2,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
@@ -14,6 +16,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/**
 * 提供可复用的 BTS TCP 脚本设备边界,用于闭环与恢复测试。
@@ -27,16 +30,21 @@
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final BlockingQueue<ScriptedAction> actions = new LinkedBlockingQueue<>();
    private final List<String> requests = new CopyOnWriteArrayList<>();
    private final Function<String, String> responseProvider;
    public ScriptedBtsTcpSimulator() throws IOException
    {
        this(true);
        this(0, true, null);
    }
    private ScriptedBtsTcpSimulator(boolean acceptConnections) throws IOException
    private ScriptedBtsTcpSimulator(int port, boolean acceptConnections,
            Function<String, String> responseProvider) throws IOException
    {
        serverSocket = new ServerSocket(0);
        port = serverSocket.getLocalPort();
        if (port < 0 || port > 65535) throw new IllegalArgumentException("port must be between 0 and 65535");
        this.responseProvider = responseProvider;
        serverSocket = new ServerSocket();
        serverSocket.bind(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), port));
        this.port = serverSocket.getLocalPort();
        if (acceptConnections)
            executor.submit(this::serve);
        else
@@ -45,7 +53,15 @@
    public static ScriptedBtsTcpSimulator refusingConnections() throws IOException
    {
        return new ScriptedBtsTcpSimulator(false);
        return new ScriptedBtsTcpSimulator(0, false, null);
    }
    /** 创建仅监听本机、可按请求持续生成响应的模拟器。 */
    public static ScriptedBtsTcpSimulator responding(int port, Function<String, String> responseProvider)
            throws IOException
    {
        if (responseProvider == null) throw new IllegalArgumentException("responseProvider must not be null");
        return new ScriptedBtsTcpSimulator(port, true, responseProvider);
    }
    public int port()
@@ -102,8 +118,11 @@
        while (!socket.isClosed())
        {
            String request = readFrame(socket.getInputStream());
            requests.add(request);
            ScriptedAction action = actions.poll(5, TimeUnit.SECONDS);
            if (responseProvider == null) requests.add(request);
            ScriptedAction action = responseProvider == null
                    ? actions.poll(5, TimeUnit.SECONDS)
                    : new ScriptedAction(Duration.ZERO,
                            responseProvider.apply(request).getBytes(StandardCharsets.UTF_8), false);
            if (action == null) throw new IOException("No scripted BTS action available");
            TimeUnit.MILLISECONDS.sleep(action.delay().toMillis());
            if (action.disconnect()) return;