Springboot串口通信+Rxtx库+JDK1.8+RS232协议

注意:RXTX库发送和接受数据是通过InputStream和OutputStream来获取和发送数据的,并且RXTX库只适用于JDK1.8_2及以下的版本

1.POM文件的导入

<dependency>
   <groupId>com.fazecast</groupId>
    <artifactId>jSerialComm</artifactId>
    <version>2.10.5</version>
</dependency>


2.写一个实体类

@Component
@AllArgsConstructor
@NoArgsConstructor
@Data
public class SerialEntity {
    @ApiModelProperty(value = "端口名称")
    private String PortName = "COM9";
    @ApiModelProperty(value = "请求指令")
    private String powerOffCommand;
    private int BAUDRATE = 2400;
    private int DATALENGTH = 8;
    private int STOPBIT = 1;
    private String PARITY = "NONE"
@ApiModelProperty(name="过载故障")
private char Overloadwarning;
@ApiModelProperty(name="过温故障")
private char Overtemperature;
@ApiModelProperty(name="电池过低故障")
private char Batterylow;
@ApiModelProperty(name="省电模式名称")
private String Batterymode;
@ApiModelProperty(name="剩余电量")
private String BatteryVoltage;
}


3.common工具类

package com.ruoyi.equipment.serialportcommon;
public class common {
        public static String HEX_STRING = "0123456789ABCDEF";
        public static final String NONE = "无";
        public static final String ODD = "奇";
        public static final String EVEN = "偶";
        public static final String FORMAT_HEX="HEX";
    }

4.SerialUtil配置类
package com.zkyq.acss.comm;
import gnu.io.SerialPort;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
public class SerialUtil {
    /**
     * 转为 HEX
     * @param str
     * @return
     */
    public static String toHex(String str){
        StringBuffer sbf = new StringBuffer();
        byte[] b = str.getBytes(StandardCharsets.UTF_8);
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sbf.append(hex.toUpperCase() + "  ");
        }
        return sbf.toString().trim();
    }
    /**
     *
     * @param hex
     * @return
     */
    public static String toStr(String hex) {
        return new String(hexToByte(hex));
    }
    /**
     * 转 HEX 字节
     * @param hex
     * @return
     */
    public static byte[] hexToByte(String hex){
        hex = hex.toUpperCase().replace(" ","");
        ByteArrayOutputStream bao = new ByteArrayOutputStream(hex.length() / 2);
        // 将每2位16进制整数组装成一个字节
        for (int i = 0; i < hex.length(); i += 2) {
            bao.write((common.HEX_STRING.indexOf(hex.charAt(i)) << 4 | common.HEX_STRING.indexOf(hex.charAt(i + 1))));
        }
        return bao.toByteArray();
    }
    /**
     * 获取校验位配置
     * @param checkBit
     * @return
     */
    public static int getParity(String checkBit){
        if (common.NONE.equals(checkBit)){
            return SerialPort.PARITY_NONE;
        } else if (common.ODD.equals(checkBit)){
            return SerialPort.PARITY_ODD;
        } else if (common.EVEN.equals(checkBit)){
            return SerialPort.PARITY_EVEN;
        } else {
            return SerialPort.PARITY_NONE;
        }
    }
    /**
     * 读取数据
     * @param in
     * @return
     */
    public static byte[] readFromPort(InputStream in) {
        byte[] bytes = {};
        try {
            // 缓冲区大小为一个字节
            byte[] readBuffer = new byte[1];
            int bytesNum = in.read(readBuffer);
            while (bytesNum > 0) {
                bytes = concat(bytes, readBuffer);
                bytesNum = in.read(readBuffer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                    in = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;
    }
    /**
     * 字节转换
     * @param format
     * @param b
     * @return
     */
    public static String printHexString(String format, byte[] b) {
        String result = new String(b);
        if (common.FORMAT_HEX.equals(format)){
            return SerialUtil.toHex(result);
        }
        return result;
    }
    /**
     * 合并数组
     *
     * @param firstArray  第一个数组
     * @param secondArray 第二个数组
     * @return 合并后的数组
     */
    public static byte[] concat(byte[] firstArray, byte[] secondArray) {
        if (firstArray == null || secondArray == null) {
            if (firstArray != null) {
                return firstArray;
            }
            if (secondArray != null) {
                return secondArray;
            }
            return null;
        }
        byte[] bytes = new byte[firstArray.length + secondArray.length];
        System.arraycopy(firstArray, 0, bytes, 0, firstArray.length);
        System.arraycopy(secondArray, 0, bytes, firstArray.length, secondArray.length);
        return bytes;
    }
}

5.RSConfig功能实现类

package com.zkyq.acss.config;
import com.zkyq.acss.comm.SerialUtil;
import com.zkyq.acss.entity.SerialEntity;
import gnu.io.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TooManyListenersException;
import java.util.concurrent.ConcurrentHashMap;
/*
* 用于配置和管理RS-232(或其他串行通信接口)端口的连接。主要功能包括打开端口、关闭端口和发送数据
* */
@Slf4j
@Component
public class Rs232Config {
    // 定义一个常量,用于表示延迟时间,单位为毫秒
    /*  private static final int DELAY_TIME = 1000;*/
    // 使用Spring的@Autowired注解,自动装配SerialPortConfig的实例
    // 使用Spring的@Autowired注解,自动装配SerialEntity的实例
private SerialUtil serialUtil;
    /**
     * 缓存端口实例
     * 使用ConcurrentHashMap以支持并发访问
     */

    private Map<String, SerialPort> serialPortMap = new ConcurrentHashMap<>(16);
    public boolean closePort(SerialEntity serial) {
        // 从map中移除并获取对应的SerialPort实例
        SerialPort serialPort = serialPortMap.remove(serial.getPortName());
        if (null != serialPort) {
            // 关闭串口
            serialPort.close();
            System.out.println("关闭串口成功");
        }
        return false;
    }
    public boolean openPort(SerialEntity serial) {
        if (serial == null) {
            log.error(("serial is null"));
            return false;
        }
        String portName = serial.getPortName();
        System.out.println("端口号" + portName);
        CommPortIdentifier portIdentifier = null;
        SerialPort serialPort = null;
        int bitRate = 0, dataBit = 0, stopBit = 0, parity = 0;
        try {
            // 获取串口对应的CommPortIdentifier对象
            portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            System.out.println("portIdentifier" + portIdentifier);
            // 打开串口,并获取SerialPort对象
            if (portIdentifier.isCurrentlyOwned()) {
                System.err.println("Error: Port is currently in use");
            } else {
                // 打开串口,并设置延迟时间为DELAY_TIME
                serialPort = (SerialPort) portIdentifier.open("", 1000);
                // 设置监听器生效,当有数据时通知
                // notifyOnDataAvailable(true) 表示当有数据到达串口时,会触发数据到达事件
                serialPort.notifyOnDataAvailable(true);
                // 从serial对象中获取串口参数(这里假设serial对象包含了这些参数)
                // 比特率
                bitRate = serial.getBAUDRATE();
                // 数据位
                dataBit = serial.getDATALENGTH();
                // 停止位
                stopBit = serial.getSTOPBIT();
                // 校验位,通过SerialUtil工具类转换为字符串表示
                parity = SerialUtil.getParity(serial.getPARITY());
                // 设置串口参数:比特率、数据位、停止位、奇偶校验位
                serialPort.setSerialPortParams(bitRate, dataBit, stopBit, parity);
            }
            // 注意:这里假设SerialPort.getParity()是存在的,实际上应该是直接传入int类型的校验位
            /*  System.out.println("是否获取到数据"+serial.getPARITY().toString());*/
        } catch (PortInUseException | NoSuchPortException e) {
            log.error("Open CommPortIdentifier {} Exception:", serial.getPortName(), e);
            return false;
        } catch (UnsupportedCommOperationException e) {
            log.error("Set SerialPortParams BitRate {} DataBit {} StopBit {} Parity {} Exception:", bitRate, dataBit, stopBit, parity, e);
            return false;
        }
        // 设置当前串口的输入输出流
        InputStream input;
        OutputStream output;
        try {
            input = serialPort.getInputStream();
            output = serialPort.getOutputStream();
        } catch (IOException e) {
            log.error("Get serialPort data stream exception:", e);
            return false;
        } catch (Exception e) {
            log.error("An error occurred while opening the port:", e);
            return false;
        }
        // 给当前串口添加一个监听器
        try {
            serialPort.addEventListener(new Serial232Listener(input, output, serial.getFormat()));
        } catch (TooManyListenersException e) {
            log.error("Get serialPort data stream exception:", e);
            return false;
        }
        serialPortMap.put(portName, serialPort);
        return true;
    }
    /**
     * 关闭端口
     *
     * @param portId 端口ID(但注意,在方法内部被硬编码为"COM5")
     */
    public SerialEntity readData(String portId) {
        SerialEntity serial = new SerialEntity();
        SerialPort serialPort = serialPortMap.get(portId);;
        InputStream input;
        try {
            input = serialPort.getInputStream();
            System.out.println("input" + input);
            byte[] bytes = serialUtil.readFromPort(input);
            System.out.println("bytes: " + bytes );
     /*       char[] charArray = new char[bytes.length];*/
            System.out.println("bytes: " );
            // 创建一个StringBuilder来构建字符串,这比使用String连接更高效
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                // 直接将字节转换为字符(假设是ASCII编码)
                char asciiChar = (char) b;
                sb.append(asciiChar);
            }
            // 将StringBuilder转换为String并打印
            String resultString = sb.toString();
            System.out.println("Received string: " + resultString); // 假设这会是"210.6"或其他有效的文本字符串
           /* String[] strArray = resultString.split("\\s+");*/
           char seven = resultString.charAt(7);
           char eight = resultString.charAt(8);
           char tweleve = resultString.charAt(12);
                serial.setBatterylow(seven);
                serial.setOverloadwarning(eight);
                serial.setOvertemperature(tweleve);
                System.out.println(serial.getBatterylow());
                System.out.println(serial.getOverloadwarning());
                System.out.println(serial.getOvertemperature());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return serial;
    }
    public SerialEntity readData1(String portId) {
        SerialEntity serial = new SerialEntity();
        SerialPort serialPort = serialPortMap.get(portId);;
        InputStream input;
        try {
            input = serialPort.getInputStream();
            System.out.println("input" + input);
            byte[] bytes = SerialUtil.readFromPort(input);
            System.out.println("bytes: " );
            // 创建一个StringBuilder来构建字符串,这比使用String连接更高效
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                // 直接将字节转换为字符(假设是ASCII编码)
                char asciiChar = (char) b;
                sb.append(asciiChar);
            }
            // 将StringBuilder转换为String并打印
            String resultString = sb.toString();
            System.out.println("Received string: " + resultString); // 假设这会是"210.6"或其他有效的文本字符串
            String[] strArray = resultString.split("\\s+");
            // 检查数组长度以确保有足够的部分
            if (strArray.length > 1) {
                // 获取第二个部分(索引为1)
                String firstPart = strArray[2];
                serial.setBatteryVoltage(firstPart);
                System.out.println(serial.getBatteryVoltage());
            } else {
                System.out.println("Not enough parts in the string.");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return serial;
    }
    public SerialEntity readData2(String portId) {
        SerialEntity serial = new SerialEntity();
        SerialPort serialPort = serialPortMap.get(portId);;
        InputStream input;
        try {
            input = serialPort.getInputStream();
            System.out.println("input" + input);
            byte[] bytes = SerialUtil.readFromPort(input);
            System.out.println("bytes: " );
            // 创建一个StringBuilder来构建字符串,这比使用String连接更高效
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                // 直接将字节转换为字符(假设是ASCII编码)
                char asciiChar = (char) b;
                sb.append(asciiChar);
            }
            // 将StringBuilder转换为String并打印
            String resultString = sb.toString();
            System.out.println("Received string: " + resultString); // 假设这会是"210.6"或其他有效的文本字符串
            String[] strArray = resultString.split("\\s+");
            // 检查数组长度以确保有足够的部分
            if (strArray.length > 0) {
                // 获取第二个部分(索引为1)
                String firstPart = strArray[0];
                serial.setBatterymode(firstPart);
                System.out.println(serial.getBatterymode());
            } else {
                System.out.println("Not enough parts in the string.");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return serial;
    }
    public boolean sendData(String portId, String message) {
        SerialPort serialPort = serialPortMap.get(portId);
        System.out.println("serialPort" + serialPort);
        if (null == serialPort){
            return false;
        }
        OutputStream output = null;
        try {
             byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
            output = serialPort.getOutputStream();
            output.write(bytes);
            output.flush();
            return true;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (null != output){
                try {
                    output.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

6.UpsManager逻辑处理类

package com.zkyq.acss.config;
import com.zkyq.acss.entity.SerialEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class UPSManager {
    // 使用Spring的自动装配特性注入Rs232Config的实例
    @Autowired
    private Rs232Config rs232Config;
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    // 关闭UPS连接的端口,并发送关机命令
    public boolean closePort(SerialEntity serial) {
        try {
            if (rs232Config != null) {
                rs232Config.openPort(serial);
                boolean closeport = rs232Config.sendData(serial.getPortName(), serial.getPowerOffCommand());
                System.out.println("closeport" + closeport);
                boolean portclosed = rs232Config.closePort(serial);
                if (portclosed) {
                    System.out.println("已发送指令");
                }
            } else {
                System.out.println("rs232Config is null");
                return false;
            }
        } catch (RuntimeException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    public boolean openPort(SerialEntity serial) {
        // 打开COM5端口(注意:这里假设portId参数未被使用)
        if (serial == null) {
            System.out.println("SerialEntity 对象为空,无法打开端口");
            return false;
        }
        if (rs232Config == null) {
            System.out.println("rs232Config 对象为空,无法操作端口" + rs232Config);
            return false;
        }
        boolean portOpened = rs232Config.openPort(serial);
        if (portOpened) {
            rs232Config.sendData(serial.getPortName(), serial.getPowerOffCommand());
            System.out.println("已发送指令");
        } else {
            System.out.println("端口未打开");
            return false;
        }
        rs232Config.closePort(serial);
        return true;
    }
    // 获取UPS的当前状态
    public SerialEntity CurrentStatus(SerialEntity serial) {
        SerialEntity SS = new SerialEntity();
        try{
            Thread.sleep(1200);
            rs232Config.openPort(serial);
            rs232Config.sendData(serial.getPortName(), serial.getPowerOffCommand());
            SS =  rs232Config.readData(serial.getPortName());
            rs232Config.closePort(serial);
        } catch (InterruptedException e) {
            System.out.println("线程被中断");
        }
        return SS;
    }
        public SerialEntity ReaminBatteryTime (SerialEntity serial) {
        SerialEntity SS = new SerialEntity();
            // 设置UPS电池剩余时间请求命令
            /*  statusRequestCommand = "F\r\n";*/
            try {
                Thread.sleep(500);
                rs232Config.openPort(serial);
                rs232Config.sendData(serial.getPortName(), serial.getPowerOffCommand());
                SS = rs232Config.readData1(serial.getPortName());
                rs232Config.closePort(serial);
                // 这里只是模拟了一个成功的请求,并返回true
            } catch (InterruptedException e) {
                System.out.println("线程被中断");
            }
            return SS;
        }
        public SerialEntity CurrentMode (SerialEntity serial){
             SerialEntity SS = new SerialEntity();
            // 设置UPS当前模式请求命令
            rs232Config.openPort(serial);
            rs232Config.sendData(serial.getPortName(), serial.getPowerOffCommand());
            SS = rs232Config.readData2(serial.getPortName());
            rs232Config.closePort(serial);
            // 这里只是模拟了一个成功的请求,并返回true
            return SS;
        }
        public boolean openPortAfterMinutes (SerialEntity serial){
            scheduler.schedule(() -> {
                try {
                    /* UPSManager upsManager = new UPSManager(); */
                    if (serial == null) {
                        System.out.println("SerialEntity 对象为空,无法打开端口");
                    }
                    if (rs232Config == null) {
                        System.out.println("rs232Config 对象为空,无法操作端口" + rs232Config);
                        // 注意:这里也不需要 return false
                    }
                    boolean portOpened = rs232Config.openPort(serial);
                    if (portOpened) {
                        rs232Config.sendData(serial.getPortName(), serial.getPowerOffCommand());
                        System.out.println("已发送指令");
                    } else {
                        System.out.println("端口未打开");
                        // 注意:这里也不需要 return false
                    }
                    rs232Config.closePort(serial);
                    // 注意:其他代码逻辑...
                    // 注意:这里不需要 return true,因为 Runnable 没有返回值
                } catch (Exception e) {
                    e.printStackTrace(); // 处理异常
                }
            }, serial.getMinutes(), TimeUnit.MINUTES);
            // 返回 true 表示操作已成功安排(但不一定已完成)
            return true;
        }
        public boolean closePortAfterMinutes (SerialEntity serial ){ // 假设你需要知道哪个端口需要被关闭
            scheduler.schedule(() -> {
                try {
                    /*  UPSManager upsManager = new UPSManager();*/
                    try {
                        if (rs232Config != null) {
                            rs232Config.openPort(serial);
                            boolean closeport = rs232Config.sendData(serial.getPortName(), serial.getPowerOffCommand());
                            System.out.println("closeport" + closeport);
                            boolean portclosed = rs232Config.closePort(serial);
                            if (portclosed) {
                                System.out.println("已发送指令");
                            }
                        } else {
                            System.out.println("rs232Config is null");
                        }
                    } catch (RuntimeException e) {
                        e.printStackTrace();
                    }
                    // 在 minutes 分钟后执行 closePort
                } catch (Exception e) {
                    e.printStackTrace(); // 处理异常
                }
            }, serial.getMinutes(), TimeUnit.MINUTES);
            // 返回 true 表示操作已成功安排(但不一定已完成)
            return true;
        }
}


7.RS232Controller请求处理类


package com.zkyq.acss.controller;
import com.zkyq.acss.config.UPSManager;
import com.zkyq.acss.entity.SerialEntity;
import com.zkyq.acss.util.ResponseObj;
import gnu.io.NoSuchPortException;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/*它用于处理与RS-232串口通信相关的HTTP请求*/
@RestController
@RequestMapping("/UPS/RS232")
@Api(tags = "UPS接入企业端")
public class Rs232Controller {
    @Autowired
    UPSManager upsManager;
 /*   @Autowired
    TimeService timeService;*/
    /**
     * 监听端口
     *
     * @param
     */
    @PostMapping("/open")
    public ResponseObj open(@RequestBody SerialEntity serial) {
        return ResponseObj.success(upsManager.openPort(serial));
    }
    @PostMapping("/close")
    public ResponseObj close(@RequestBody SerialEntity serial) {
        /*    serialController.getSerialPortList();*/
        return ResponseObj.success(upsManager.closePort(serial));
    }
    @PostMapping("/CurrentStatus")
    public ResponseObj CurrentStatus(@RequestBody SerialEntity serial) throws IOException, NoSuchPortException {
        return ResponseObj.success(upsManager.CurrentStatus(serial));
    }
    @PostMapping("/ReaminBatteryTime")
    public ResponseObj ReaminBatteryTime(@RequestBody SerialEntity serial) {
        /* serialController.getSerialPortList();*/
        return ResponseObj.success(upsManager.ReaminBatteryTime(serial));
    }
    @PostMapping("/CurrentMode")
    public ResponseObj CurrentMode(@RequestBody SerialEntity serial) {
        return ResponseObj.success(upsManager.CurrentMode(serial));
    }
//设置几分钟后自动开启   
    @PostMapping("/time")
    public ResponseObj Time(@RequestBody SerialEntity serial) {
        return ResponseObj.success(upsManager.openPortAfterMinutes(serial));
    }
//设置几分钟后自动关闭
    @PostMapping("/time2")
    public ResponseObj Time2(@RequestBody SerialEntity serial) {
        return ResponseObj.success( upsManager.closePortAfterMinutes(serial));
    }
}

                        

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中使用RXTX进行串口通信,可以按照以下步骤进行: 1. 添加RXTX依赖 在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.rxtx</groupId> <artifactId>rxtx</artifactId> <version>2.2</version> </dependency> ``` 2. 配置串口信息 在application.properties文件中添加以下配置信息: ```properties serial.port.name=COM1 # 串口名称 serial.port.baudrate=9600 # 波特率 serial.port.databits=8 # 数据位 serial.port.stopbits=1 # 停止位 serial.port.parity=0 # 校验位 ``` 3. 创建SerialPortService类 创建一个SerialPortService类,用于打开、关闭串口,发送和接收数据。代码如下: ```java @Service public class SerialPortService { private SerialPort serialPort; public void open(String portName, int baudRate, int dataBits, int stopBits, int parity) throws Exception { CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); if (portIdentifier.isCurrentlyOwned()) { throw new Exception("Port is currently in use"); } else { CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000); if (commPort instanceof SerialPort) { serialPort = (SerialPort) commPort; serialPort.setSerialPortParams(baudRate, dataBits, stopBits, parity); } else { throw new Exception("Only serial ports are supported"); } } } public void close() { if (serialPort != null) { serialPort.close(); } } public void send(String data) throws Exception { if (serialPort != null) { OutputStream outputStream = serialPort.getOutputStream(); outputStream.write(data.getBytes()); outputStream.flush(); } else { throw new Exception("Serial port is not open"); } } public String receive() throws Exception { if (serialPort != null) { InputStream inputStream = serialPort.getInputStream(); byte[] buffer = new byte[1024]; int len = inputStream.read(buffer); return new String(buffer, 0, len); } else { throw new Exception("Serial port is not open"); } } } ``` 4. 创建Controller类 创建一个Controller类,用于处理HTTP请求和WebSocket请求。代码如下: ```java @RestController public class SerialPortController { @Autowired private SerialPortService serialPortService; @GetMapping("/open") public String open() throws Exception { serialPortService.open( Environment.getProperty("serial.port.name"), Integer.parseInt(Environment.getProperty("serial.port.baudrate")), Integer.parseInt(Environment.getProperty("serial.port.databits")), Integer.parseInt(Environment.getProperty("serial.port.stopbits")), Integer.parseInt(Environment.getProperty("serial.port.parity")) ); return "Serial port is open"; } @GetMapping("/close") public String close() { serialPortService.close(); return "Serial port is closed"; } @GetMapping("/send") public String send(@RequestParam String data) throws Exception { serialPortService.send(data); return "Data is sent"; } @MessageMapping("/receive") @SendTo("/topic/receive") public String receive() throws Exception { return serialPortService.receive(); } } ``` 5. 创建WebSocket配置类 创建一个WebSocket配置类,用于配置WebSocket。代码如下: ```java @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").withSockJS(); } } ``` 6. 创建WebSocket客户端 创建一个WebSocket客户端,用于向服务器发送WebSocket请求和接收服务器的响应。代码如下: ```javascript var stompClient = null; function connect() { var socket = new SockJS('/ws'); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { console.log('Connected: ' + frame); stompClient.subscribe('/topic/receive', function (message) { console.log('Received: ' + message.body); }); }); } function send() { var data = document.getElementById('data').value; stompClient.send('/app/send', {}, data); } ``` 7. 创建HTML页面 创建一个HTML页面,用于测试串口通信。代码如下: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Serial Port Test</title> <script src="/webjars/sockjs-client/1.5.0/dist/sockjs.min.js"></script> <script src="/webjars/stomp-websocket/2.3.3/dist/stomp.min.js"></script> <script src="/js/app.js"></script> </head> <body onload="connect()"> <input type="text" id="data"> <button onclick="send()">Send</button> </body> </html> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值