当前位置:   article > 正文

Java使用RXTX进行串口SerialPort通讯_java serialport

java serialport

RXTX简介 (https://www.jianshu.com/p/cb61f797ffc1

RXTX是一个提供串口和并口通信的开源java类库,由该项目发布的文件均遵循LGPL协议。
RXTX项目提供了Windows,Linux,Mac os X,Solaris操作系统下的兼容javax.comm串口通讯包API的实现,为其他开发人员在此类系统下开发串口应用提供了相当的方便。
RXTX的使用上与sun提供的comm.jar基本相同,编程时最明显的不同是要包含的包名由javax.comm.改成了gnu.io.

RxtxAPI 的核心是抽象的CommPort类(用于描述一个被底层系统支持的端口的抽象类,它包含一些高层的IO控制方法,这些方法对于所有不同的通讯端口来说是通用的)及其两个子类:SerialPort类和ParallePort类。其中,SerialPort类是用于串口通信的类,ParallePort类是用于并行口通信的类。CommPort类还提供了常规的通信模式和方法,例如:getInputStream( )方法和getOutputStream( )方法,专用于与端口上的设备进行通信。
然而,这些类的构造方法都被有意的设置为非公有的(non-public)。所以,不能直接构造对象,而是先通过静态的CommPortIdentifer.getPortIdentifiers()获得端口列表,再从这个端口列表中选择所需要的端口,并调用CommPortIdentifer对象的Open( )方法,这样,就能得到一个CommPort对象。当然,还要将这个CommPort对象的类型转换为某个非抽象的子类,表明是特定的通讯设备,该子类可以是SerialPort类和ParallePort类中的一个。下面将分别对CommPortIdentifier类,串口类SerialPort进行详细的介绍。

 

  1. 接口
  2. CommDriver可负载设备(the loadable device)驱动程序接口的一部分
  3. CommPortOwnershipListener传递各种通讯端口的所有权事件
  4. ParallelPortEventListener传递并行端口事件
  5. SerialPortEventListener传递串行端口事件
  6. CommPort通讯端口
  7. CommPortIdentifier通讯端口管理
  8. ParallelPort并行通讯端口
  9. ParallelPortEvent并行端口事件
  10. SerialPortRS-232串行通讯端口
  11. SerialPortEvent 串行端口事件
  12. 异常类
  13. NoSuchPortException当驱动程序不能找到指定端口时抛出
  14. PortInUseException当碰到指定端口正在使用中时抛出
  15. UnsupportedCommOperationException驱动程序不允许指定操作时抛出
  16. CommPortIdentifier类
  17. 这个类主要用于对通信端口进行管理和设置,是对端口进行访问控制的核心类,主要包括以下方法:
  18. addPortName(String,int, CommDriver) 添加端口名到端口列表里
  19. addPortOwnershipListener(CommPortOwnershipListener)添加端口拥有的监听器
  20. removePortOwnershipListener(CommPortOwnershipListener)移除端口拥有的监听器
  21. getCurrentOwner()获取当前占有端口的对象或应用程序
  22. getName()获取端口名称
  23. getPortIdentifier(CommPort)获取指定打开的端口的CommPortIdentifier类型对象
  24. getPortIdentifier(String)获取以参数命名的端口的CommPortIdentifier类型对象
  25. getPortIdentifiers()获取系统中的端口列表
  26. getPortType()获取端口的类型
  27. isCurrentlyOwned()判断当前端口是否被占用
  28. open(FileDescriptor)用文件描述的类型打开端口
  29. open(String,int) 打开端口,两个参数:程序名称,延迟时间(毫秒数)
  30. SerialPort类
  31. 这个类用于描述一个RS-232串行通信端口的底层接口,它定义了串口通信所需的最小功能集。通过它,用户可以直接对串口进行读、写及设置工作。
  32. SerialPort类中关于串口参数的静态成员变量说明:
  33. DATABITS_5 数据位为5
  34. DATABITS_6 数据位为6
  35. DATABITS_7 数据位为7
  36. DATABITS_8 数据位为8
  37. PARITY_NONE 空格检验
  38. PARITY_ODD 奇检验
  39. PARITY_EVEN 偶检验
  40. PARITY_MARK 标记检验
  41. PARITY_SPACE 无检验
  42. STOPBITS_1 停止位为1
  43. STOPBITS_2 停止位为2
  44. STOPBITS_1_5 停止位为1.5
  45. SerialPort类中关于串口参数的方法说明:
  46. getBaudRate()得到波特率
  47. getParity()得到检验类型
  48. getDataBits()得到数据位数
  49. getStopBits()得到停止位数
  50. setSerialPortParams(int,int, int, int) 设置串口参数依次为(波特率,数据位,停止位,奇偶检验)
  51. SerialPort类中关于事件的静态成员变量说明:
  52. BI Break interrupt 通讯中断
  53. FE Framing error 帧错误
  54. CD Carrier detect 载波侦听
  55. OE Overrun error 溢位错误
  56. CTS Clear to send 清除发送
  57. PE Parity error 奇偶检验错误
  58. DSR Data set ready 数据设备准备好
  59. RI Ring indicator 响铃侦测
  60. DATA_AVAILABLE 串口中的可用数据
  61. OUTPUT_BUFFER_EMPTY 输出缓冲区已清空
  62. SerialPort类中关于事件的方法说明:
  63. isCD()是否有载波
  64. isCTS()是否清除以传送
  65. isDSR()数据是否备妥
  66. isDTR()是否数据端备妥
  67. isRI()是否响铃侦测
  68. isRTS()是否要求传送
  69. addEventListener(SerialPortEventListener)向SerialPort对象中添加串口事件监听器
  70. removeEventListener()移除SerialPort对象中的串口事件监听器
  71. notifyOnBreakInterrupt(boolean)设置中断事件true有效,false无效
  72. notifyOnCarrierDetect(boolean)设置载波监听事件true有效,false无效
  73. notifyOnCTS(boolean)设置清除发送事件true有效,false无效
  74. notifyOnDataAvailable(boolean)设置串口有数据的事件true有效,false无效
  75. notifyOnDSR(boolean)设置数据备妥事件true有效,false无效
  76. notifyOnFramingError(boolean)设置发生错误事件true有效,false无效
  77. notifyOnOutputEmpty(boolean)设置发送缓冲区为空事件true有效,false无效
  78. notifyOnParityError(boolean)设置发生奇偶检验错误事件true有效,false无效
  79. notifyOnRingIndicator(boolean)设置响铃侦测事件true有效,false无效
  80. getEventType()得到发生的事件类型返回值为int型
  81. sendBreak(int)设置中断过程的时间,参数为毫秒值
  82. setRTS(boolean)设置或清除RTS位
  83. setDTR(boolean)设置或清除DTR位
  84. SerialPort中的其他常用方法说明:
  85. close()关闭串口
  86. getOutputStream()得到OutputStream类型的输出流
  87. getInputStream()得到InputStream类型的输入流

准备工作

  • RXTX包:rxtx-2.2pre2-bins.zip
  • 串口虚拟工具:vspd.exe
  • 串口调试工具:amcktszs_v2.4.0.0.exe

安装RXTX包

解压rxtx-2.2pre2-bins.zip,将RXTXcomm.jar加入项目依赖库里,对应操作的系统的rxtxSerial.dll和rxtxParallel.dll文件放入jdk的bin目录下

 

  1. 前提条件:maven已经加入环境变量中
  2. mvn install:install-file -DgroupId=gnu.io -DartifactId=RXTXcomm -Dversion=1.0 -Dpackaging=jar -Dfile=E:\Work\Yotrio\libs\RXTXcomm.jar

工具创建一对虚拟串口

Image.png

打开串口调试工具,配置串口参数

Image [2].png

样例Demo

封装串口读写工具类

 

  1. /**
  2. * 模块名称:projects-parent com.yotrio.common
  3. * 功能说明:串口服务类,提供打开、关闭串口,读取、发送串口数据等服务(采用单例设计模式)
  4. * <br>
  5. * 开发人员:Wangyq
  6. * 创建时间: 2018-09-20 10:05
  7. * 系统版本:1.0.0
  8. **/
  9. public class SerialPortUtil {
  10. private static SerialPortUtil serialPortUtil = null;
  11. static {
  12. //在该类被ClassLoader加载时就初始化一个SerialTool对象
  13. if (serialPortUtil == null) {
  14. serialPortUtil = new SerialPortUtil();
  15. }
  16. }
  17. //私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象
  18. private SerialPortUtil() {
  19. }
  20. /**
  21. * 获取提供服务的SerialTool对象
  22. *
  23. * @return serialPortUtil
  24. */
  25. public static SerialPortUtil getSerialPortUtil() {
  26. if (serialPortUtil == null) {
  27. serialPortUtil = new SerialPortUtil();
  28. }
  29. return serialPortUtil;
  30. }
  31. /**
  32. * 查找所有可用端口
  33. *
  34. * @return 可用端口名称列表
  35. */
  36. public static final ArrayList<String> findPort() {
  37. //获得当前所有可用串口
  38. Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();
  39. ArrayList<String> portNameList = new ArrayList<>();
  40. //将可用串口名添加到List并返回该List
  41. while (portList.hasMoreElements()) {
  42. String portName = portList.nextElement().getName();
  43. portNameList.add(portName);
  44. }
  45. return portNameList;
  46. }
  47. /**
  48. * 打开串口
  49. *
  50. * @param portName 端口名称
  51. * @param baudrate 波特率
  52. * @param databits 数据位
  53. * @param parity 校验位(奇偶位)
  54. * @param stopbits 停止位
  55. * @return 串口对象
  56. * @throws SerialPortParameterFailure 设置串口参数失败
  57. * @throws NotASerialPort 端口指向设备不是串口类型
  58. * @throws NoSuchPort 没有该端口对应的串口设备
  59. * @throws PortInUse 端口已被占用
  60. */
  61. public static final SerialPort openPort(String portName, int baudrate, int databits, int parity, int stopbits) throws SerialPortParameterFailure, NotASerialPort, NoSuchPort, PortInUse {
  62. try {
  63. //通过端口名识别端口
  64. CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
  65. //打开端口,并给端口名字和一个timeout(打开操作的超时时间)
  66. CommPort commPort = portIdentifier.open(portName, 2000);
  67. //判断是不是串口
  68. if (commPort instanceof SerialPort) {
  69. SerialPort serialPort = (SerialPort) commPort;
  70. try {
  71. //设置一下串口的波特率等参数
  72. serialPort.setSerialPortParams(baudrate, databits, stopbits, parity);
  73. } catch (UnsupportedCommOperationException e) {
  74. throw new SerialPortParameterFailure();
  75. }
  76. //System.out.println("Open " + portName + " sucessfully !");
  77. return serialPort;
  78. } else {
  79. //不是串口
  80. throw new NotASerialPort();
  81. }
  82. } catch (NoSuchPortException e1) {
  83. throw new NoSuchPort();
  84. } catch (PortInUseException e2) {
  85. throw new PortInUse();
  86. }
  87. }
  88. /**
  89. * 关闭串口
  90. *
  91. * @param serialPort 待关闭的串口对象
  92. */
  93. public static void closePort(SerialPort serialPort) {
  94. if (serialPort != null) {
  95. serialPort.close();
  96. serialPort = null;
  97. }
  98. }
  99. /**
  100. * 往串口发送数据
  101. *
  102. * @param serialPort 串口对象
  103. * @param order 待发送数据
  104. * @throws SendDataToSerialPortFailure 向串口发送数据失败
  105. * @throws SerialPortOutputStreamCloseFailure 关闭串口对象的输出流出错
  106. */
  107. public static void sendToPort(SerialPort serialPort, byte[] order) throws SendDataToSerialPortFailure, SerialPortOutputStreamCloseFailure {
  108. OutputStream out = null;
  109. try {
  110. out = serialPort.getOutputStream();
  111. out.write(order);
  112. out.flush();
  113. } catch (IOException e) {
  114. throw new SendDataToSerialPortFailure();
  115. } finally {
  116. try {
  117. if (out != null) {
  118. out.close();
  119. out = null;
  120. }
  121. } catch (IOException e) {
  122. throw new SerialPortOutputStreamCloseFailure();
  123. }
  124. }
  125. }
  126. /**
  127. * 从串口读取数据
  128. *
  129. * @param serialPort 当前已建立连接的SerialPort对象
  130. * @return 读取到的数据
  131. * @throws ReadDataFromSerialPortFailure 从串口读取数据时出错
  132. * @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错
  133. */
  134. public static byte[] readFromPort(SerialPort serialPort) throws ReadDataFromSerialPortFailure, SerialPortInputStreamCloseFailure {
  135. InputStream in = null;
  136. byte[] bytes = null;
  137. try {
  138. in = serialPort.getInputStream();
  139. int bufflenth = in.available(); //获取buffer里的数据长度
  140. while (bufflenth != 0) {
  141. bytes = new byte[bufflenth]; //初始化byte数组为buffer中数据的长度
  142. in.read(bytes);
  143. bufflenth = in.available();
  144. }
  145. } catch (IOException e) {
  146. throw new ReadDataFromSerialPortFailure();
  147. } finally {
  148. try {
  149. if (in != null) {
  150. in.close();
  151. in = null;
  152. }
  153. } catch (IOException e) {
  154. throw new SerialPortInputStreamCloseFailure();
  155. }
  156. }
  157. return bytes;
  158. }
  159. /**
  160. * 添加监听器
  161. *
  162. * @param port 串口对象
  163. * @param listener 串口监听器
  164. * @throws TooManyListeners 监听类对象过多
  165. */
  166. public static void addListener(SerialPort port, SerialPortEventListener listener) throws TooManyListeners {
  167. try {
  168. //给串口添加监听器
  169. port.addEventListener(listener);
  170. //设置当有数据到达时唤醒监听接收线程
  171. port.notifyOnDataAvailable(true);
  172. //设置当通信中断时唤醒中断线程
  173. port.notifyOnBreakInterrupt(true);
  174. } catch (TooManyListenersException e) {
  175. throw new TooManyListeners();
  176. }
  177. }
  178. /**
  179. * 删除监听器
  180. *
  181. * @param port 串口对象
  182. * @param listener 串口监听器
  183. * @throws TooManyListeners 监听类对象过多
  184. */
  185. public static void removeListener(SerialPort port, SerialPortEventListener listener) {
  186. //删除串口监听器
  187. port.removeEventListener();
  188. }
  189. }

整合websocket获取并推送给前台页面实时显示

 

  1. @ServerEndpoint(value = "/websocket") //接受websocket请求路径
  2. @Component
  3. public class PoundWebSocket {
  4. private Logger logger = LoggerFactory.getLogger(this.getClass());
  5. /**
  6. * 保存所有在线socket连接
  7. */
  8. private static Map<String, PoundWebSocket> webSocketMap = new LinkedHashMap<>();
  9. /**
  10. * 记录当前在线数目
  11. */
  12. private static int count = 0;
  13. /**
  14. * 当前连接(每个websocket连入都会创建一个MyWebSocket实例
  15. */
  16. private Session session;
  17. /**
  18. * 创建监听串口
  19. */
  20. private static SerialPort serialPort = null;
  21. /**
  22. * 创建监听器
  23. */
  24. private static SerialPortEventListener serialPortEventListener = null;
  25. /**
  26. * 监听串口
  27. */
  28. private static String PORT_NAME;
  29. /**
  30. * 监听串口波特率
  31. */
  32. private static int BAUD_RATE;
  33. /**
  34. * 数据位
  35. */
  36. private static int DATA_BITS;
  37. /**
  38. * 停止位
  39. */
  40. private static int STOP_BITS;
  41. /**
  42. * 奇偶位
  43. */
  44. private static int PARITY;
  45. /**
  46. * 地磅型号
  47. */
  48. private static String MODEL;
  49. private static IPoundInfoService poundInfoService;
  50. private static ApplicationContext applicationContext;
  51. public static void setApplicationContext(ApplicationContext applicationContext) {
  52. PoundWebSocket.applicationContext = applicationContext;
  53. }
  54. private static StringBuffer stringBuffer = new StringBuffer();
  55. /**
  56. * 处理连接建立
  57. *
  58. * @param session
  59. */
  60. @OnOpen
  61. public void onOpen(Session session) {
  62. if (poundInfoService == null) {
  63. poundInfoService = applicationContext.getBean(IPoundInfoService.class);
  64. }
  65. //获取地磅信息
  66. PoundInfo poundInfo = poundInfoService.findOne();
  67. PORT_NAME = poundInfo.getSerialPort();
  68. BAUD_RATE = poundInfo.getBaudRate();
  69. MODEL = poundInfo.getModel();
  70. DATA_BITS = poundInfo.getDataBits() != null ? poundInfo.getDataBits() : SerialPort.DATABITS_8;
  71. STOP_BITS = poundInfo.getStopBits() != null ? poundInfo.getStopBits() : SerialPort.STOPBITS_1;
  72. PARITY = poundInfo.getParity() != null ? poundInfo.getParity() : SerialPort.PARITY_NONE;
  73. this.session = session;
  74. webSocketMap.put(session.getId(), this);
  75. addCount();
  76. // logger.info("新的连接加入:{}", session.getId());
  77. try {
  78. //确保串口已被关闭,未关闭会导致重新监听串口失败
  79. if (serialPort != null) {
  80. SerialPortUtil.closePort(serialPort);
  81. serialPort = null;
  82. }
  83. //创建串口 COM5位串口名称 9600波特率
  84. if (serialPort == null && StringUtils.isNotEmpty(PORT_NAME) && StringUtils.isNotEmpty(MODEL)) {
  85. serialPort = SerialPortUtil.openPort(PORT_NAME, BAUD_RATE, DATA_BITS, PARITY, STOP_BITS);
  86. // logger.info("创建串口:{}", serialPort);
  87. //设置串口监听
  88. SerialPortUtil.addListener(serialPort, new SerialPortEventListener() {
  89. @Override
  90. public void serialEvent(SerialPortEvent serialPortEvent) {
  91. if (serialPortEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
  92. try {
  93. //读取串口数据
  94. byte[] bytes = SerialPortUtil.readFromPort(serialPort);
  95. //根据型号解析字符串
  96. switch (MODEL) {
  97. case PoundConstant.MODEL_XK_3190:
  98. parsingString1(bytes);
  99. break;
  100. case PoundConstant.MODEL_XK_3190_10:
  101. parsingString2(bytes);
  102. break;
  103. case PoundConstant.MODEL_D_2008:
  104. parsingString1(bytes);
  105. break;
  106. case PoundConstant.MODEL_DK_3230_D_6:
  107. parsingString3(bytes);
  108. break;
  109. case PoundConstant.MODEL_D_2009_F:
  110. parsingString4(bytes);
  111. break;
  112. default:
  113. String value = String.valueOf(Integer.valueOf(new String(bytes, "GB2312")) - RandomUtil.randomInt(1000, 10000));
  114. sendMessageToAll(value);
  115. }
  116. // System.out.println("收到的数据:" + new String(bytes, "GB2312") + "----" + new Date());
  117. } catch (ReadDataFromSerialPortFailure readDataFromSerialPortFailure) {
  118. logger.error(readDataFromSerialPortFailure.toString());
  119. } catch (SerialPortInputStreamCloseFailure serialPortInputStreamCloseFailure) {
  120. logger.error(serialPortInputStreamCloseFailure.toString());
  121. } catch (UnsupportedEncodingException e) {
  122. logger.error(e.toString());
  123. } catch (IOException e) {
  124. logger.error(e.toString());
  125. }
  126. }
  127. }
  128. });
  129. }
  130. } catch (SerialPortParameterFailure serialPortParameterFailure) {
  131. logger.error(serialPortParameterFailure.toString());
  132. } catch (NotASerialPort notASerialPort) {
  133. logger.error(notASerialPort.toString());
  134. } catch (NoSuchPort noSuchPort) {
  135. logger.error(noSuchPort.toString());
  136. } catch (PortInUse portInUse) {
  137. logger.error(portInUse.toString());
  138. } catch (TooManyListeners tooManyListeners) {
  139. logger.error(tooManyListeners.toString());
  140. }
  141. }
  142. /**
  143. * 解析字符串 方法1
  144. *
  145. * @param bytes 获取的字节码
  146. */
  147. private void parsingString1(byte[] bytes) {
  148. StringBuffer sb = new StringBuffer();
  149. //将ASCII码转成字符串
  150. for (int i = 0; i < bytes.length; i++) {
  151. sb.append((char) Integer.parseInt(String.valueOf(bytes[i])));
  152. }
  153. //解析字符串
  154. String[] strs = sb.toString().trim().split("\\+");
  155. int weight = 0;
  156. for (int j = 0; j < strs.length; j++) {
  157. if (strs[j].trim().length() >= 6) {
  158. weight = Integer.parseInt(strs[j].trim().substring(0, 6));
  159. //发送数据
  160. sendMessageToAll(String.valueOf(weight));
  161. break;
  162. }
  163. }
  164. }
  165. /**
  166. * 解析字符串 方法2
  167. *
  168. * @param bytes 获取的字节码
  169. */
  170. private void parsingString2(byte[] bytes) {
  171. StringBuffer sb = new StringBuffer();
  172. //将ASCII码转成字符串
  173. for (int i = 0; i < bytes.length; i++) {
  174. sb.append((char) Integer.parseInt(String.valueOf(bytes[i])));
  175. }
  176. //解析字符串
  177. String[] strs = sb.toString().trim().split("\\+");
  178. double weight = 0;
  179. for (int j = 0; j < strs.length; j++) {
  180. if (strs[j].trim().length() >= 6) {
  181. weight = Double.parseDouble(strs[j].trim().substring(0, 6)) / 10;
  182. //发送数据
  183. sendMessageToAll(String.valueOf(weight));
  184. break;
  185. }
  186. }
  187. }
  188. /**
  189. * 解析字符串 方法3
  190. *
  191. * @param bytes 获取的字节码
  192. */
  193. private void parsingString3(byte[] bytes) {
  194. StringBuffer sb = new StringBuffer();
  195. //将ASCII码转成字符串
  196. for (int i = 0; i < bytes.length; i++) {
  197. sb.append((char) Integer.parseInt(String.valueOf(bytes[i])));
  198. }
  199. // logger.info("sb:" + sb.toString());
  200. sb.reverse();
  201. //解析字符串
  202. String[] strs = sb.toString().trim().split("\\=");
  203. double weight = 0;
  204. for (int j = 0; j < strs.length; j++) {
  205. if (strs[j].trim().length() >= 6) {
  206. weight = Double.parseDouble(strs[j].trim());
  207. //发送数据
  208. sendMessageToAll(String.valueOf(weight));
  209. break;
  210. }
  211. }
  212. }
  213. /**
  214. * 解析字符串 方法3
  215. *
  216. * @param bytes 获取的字节码
  217. */
  218. private void parsingString4(byte[] bytes) {
  219. StringBuffer sb = new StringBuffer();
  220. //将ASCII码转成字符串
  221. for (int i = 0; i < bytes.length; i++) {
  222. sb.append((char) Integer.parseInt(String.valueOf(bytes[i])));
  223. }
  224. // logger.info("sb:" + sb.reverse());
  225. //字符串反转
  226. sb.reverse();
  227. //解析字符串
  228. String[] strs = sb.toString().trim().split("\\=");
  229. int weight = 0;
  230. for (int j = 0; j < strs.length; j++) {
  231. if (strs[j].trim().length() >= 6) {
  232. weight = Integer.parseInt(strs[j].trim().substring(0, 6));
  233. //发送数据
  234. sendMessageToAll(String.valueOf(weight));
  235. break;
  236. }
  237. }
  238. }
  239. /**
  240. * 接受消息
  241. *
  242. * @param message
  243. * @param session
  244. */
  245. @OnMessage
  246. public void onMessage(String message, Session session) {
  247. logger.info("收到客户端{}消息:{}", session.getId(), message);
  248. try {
  249. this.sendMessage(message);
  250. } catch (Exception e) {
  251. logger.error(e.toString());
  252. }
  253. }
  254. /**
  255. * 处理错误
  256. *
  257. * @param error
  258. * @param session
  259. */
  260. @OnError
  261. public void onError(Throwable error, Session session) {
  262. logger.info("发生错误{},{}", session.getId(), error.getMessage());
  263. }
  264. /**
  265. * 处理连接关闭
  266. */
  267. @OnClose
  268. public void onClose() {
  269. webSocketMap.remove(this.session.getId());
  270. reduceCount();
  271. logger.info("连接关闭:{}", this.session.getId());
  272. //连接关闭后关闭串口,下一次打开连接重新监听串口
  273. if (serialPort != null) {
  274. SerialPortUtil.closePort(serialPort);
  275. serialPort = null;
  276. }
  277. }
  278. /**
  279. * 群发消息
  280. *
  281. * @param message
  282. */
  283. public void sendMessageToAll(String message) {
  284. for (int i = 0; i < webSocketMap.size(); i++) {
  285. try {
  286. // logger.info("session:id=" + session.getId());
  287. this.session.getBasicRemote().sendText(message);
  288. } catch (IOException e) {
  289. logger.error(e.getMessage());
  290. }
  291. }
  292. }
  293. /**
  294. * 发送消息
  295. *
  296. * @param message
  297. * @throws IOException
  298. */
  299. public void sendMessage(String message) throws IOException {
  300. // logger.info("session:id=" + session.getId());
  301. this.session.getBasicRemote().sendText(message);
  302. }
  303. //广播消息
  304. public static void broadcast() {
  305. PoundWebSocket.webSocketMap.forEach((k, v) -> {
  306. try {
  307. v.sendMessage("这是一条测试广播");
  308. } catch (Exception e) {
  309. }
  310. });
  311. }
  312. //获取在线连接数目
  313. public static int getCount() {
  314. return count;
  315. }
  316. //操作count,使用synchronized确保线程安全
  317. public static synchronized void addCount() {
  318. PoundWebSocket.count++;
  319. }
  320. public static synchronized void reduceCount() {
  321. PoundWebSocket.count--;
  322. }
  323. }

 



作者:小土豆哥哥
链接:https://www.jianshu.com/p/cb61f797ffc1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/289720
推荐阅读
相关标签
  

闽ICP备14008679号