jbase仪器接口设计

jbase的计划有借助虚拟M来实现连仪器,之前陆续写了些TCP逻辑,今天终于整理完成了仪器设计。首先用java的cs程序测试TCP的服务和客户端。

javafx的示例加强

package sample;import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.ScrollPane;import java.awt.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;public class Main extends Application {//数字static int num = 0;//场景Scene scene;//场景1Scene scene1;//定时发送Socket sendSocket = null;//自动发送次数int sendNum = 0;//通讯日志StringBuilder sbLog=new StringBuilder();//换行符String lineStr=System.getProperty("line.separator");@Overridepublic void start(Stage stage) throws Exception {//舞台标题stage.setTitle("第一个java程序");// 流式布局:按照控件的添加次序按个摆放,按照从上到下、从左到右的次序摆放。FlowPane pane = new FlowPane(5, 5);// 居中显示pane.setAlignment(Pos.CENTER);// 场景scene = new Scene(pane, 800, 600);// 标签Label label = new Label("初始值:" + num);// 加1按钮Button addButton = new Button("加1");addButton.setOnMouseClicked(e -> {num++;label.setText("当前值:" + num);});//减1按钮Button subButton = new Button("减1");subButton.setOnMouseClicked(e -> {num--;label.setText("当前值:" + num);});//切换到场景1Button btnScene1 = new Button("场景1");btnScene1.setOnMouseClicked(e -> {stage.setScene(scene1);});//弹出一个子窗口Button btnShowChildForm = new Button("子窗口");btnShowChildForm.setOnMouseClicked(e -> {Child.ShowChild("子窗口", "传给子窗口的参数");});// 创建一个TextArea控件TextArea textArea = new TextArea();textArea.setWrapText(true); // 设置文本自动换行//定时器,主动上传时候用Timer timer = new Timer();TimerTask task = new TimerTask() {@Overridepublic void run() {if (sendSocket != null) {try {sendNum++;// 发送请求消息到服务端OutputStream outputStream = sendSocket.getOutputStream();PrintWriter out = new PrintWriter(new OutputStreamWriter(outputStream, "GBK"), true);out.println("这是定时发送的第" + sendNum + "次数据");out.flush();} catch (Exception ex) {}}}};// 设置定时器的执行策略,延迟0秒后开始执行,每隔1秒执行一次timer.schedule(task, 0, 5000);//启动tcp服务Button btnTcpServer = new Button("TCP服务");btnTcpServer.setOnMouseClicked(e -> {Thread clientThread = new Thread(new Runnable() {@Overridepublic void run() {try {ServerSocket serverSocket = new ServerSocket(8888);//增加一个无限循环while (true) {sbLog.append("服务启动"+lineStr);System.out.println("服务启动");//通知界面javafx.application.Platform.runLater(()->{textArea.setText(sbLog.toString());});//等待客户端连接,阻塞Socket clientSocket = serverSocket.accept();sendSocket = clientSocket;//得到输出流PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);System.out.println("客户端连接");sbLog.append("客户端连接"+lineStr);//通知界面javafx.application.Platform.runLater(()->{textArea.setText(sbLog.toString());});//得到输入流InputStream inputStream = clientSocket.getInputStream();//IO读取byte[] buf = new byte[10240];int readlen = 0;//阻塞读取数据while ((readlen = inputStream.read(buf)) != -1) {System.out.println(new String(buf, 0, readlen, "GBK"));sbLog.append(new String(buf, 0, readlen, "GBK")+lineStr);//通知界面javafx.application.Platform.runLater(()->{textArea.setText(sbLog.toString());});}//关闭输入inputStream.close();//关闭输出out.close();clientSocket.close();}} catch (Exception e) {}}});clientThread.start();});//启动tcp客户端Button btnTcpClient = new Button("TCP客户端");btnTcpClient.setOnMouseClicked(e -> {Thread clientThread = new Thread(new Runnable() {@Overridepublic void run() {try {try {// 创建 Socket 对象并连接到服务端Socket socket = new Socket("172.16.1.232", 1991);sendSocket = socket;// 发送请求消息到服务端OutputStream outputStream = socket.getOutputStream();PrintWriter out = new PrintWriter(new OutputStreamWriter(outputStream, "GBK"), true);out.println("你好,我是客户端");out.flush();//得到输入流InputStream inputStream = socket.getInputStream();//IO读取byte[] buf = new byte[10240];int readlen = 0;//阻塞读取数据while ((readlen = inputStream.read(buf)) != -1) {System.out.println(new String(buf, 0, readlen, "GBK"));sbLog.append(new String(buf, 0, readlen, "GBK")+lineStr);out.println("我已经收到数据");//通知界面javafx.application.Platform.runLater(()->{textArea.setText(sbLog.toString());});}//关闭输入inputStream.close();//关闭输出out.close();// 关闭连接socket.close();} catch (IOException ex) {ex.printStackTrace();}} catch (Exception e) {}}});clientThread.start();});pane.getChildren().addAll(addButton, subButton, btnScene1, btnShowChildForm, label, textArea, btnTcpServer, btnTcpClient);// 场景1// 流式布局:按照控件的添加次序按个摆放,按照从上到下、从左到右的次序摆放。FlowPane pane1 = new FlowPane(10, 10);// 居中显示pane1.setAlignment(Pos.CENTER);scene1 = new Scene(pane1, 200, 150);//返回开始的场景Button btnReturn = new Button("返回");btnReturn.setOnMouseClicked(e -> {stage.setScene(scene);});pane1.getChildren().addAll(btnReturn);//默认场景和显示stage.setScene(scene);stage.show();}public static void main(String[] args) {launch(args);}
}

在这里插入图片描述

客户端测试成功后设计jbase仪器基础,这里首先要理解连设备的本质,连TCP设备的话,其实真正的业务只关心我当做客户端还是服务端、以什么编码、然后解析和发送数据,我并不想关系TCP的实现细节。所以可以把初始化TCP和处理数据及定时上传以接口形式抽取出来。

先抽取处理仪器数据接口IMachDealData,具体仪器只需要实现该接口即可,抽取变性很重要

package LIS.Core.Socket;import java.io.PrintWriter;
import java.net.Socket;/*** 仪器处理数据接口,具体的仪器接口实现此接口后初始化MachSocketBase对象*/
public interface IMachDealData {/*** 处理上传定时器接口* @param sender Socket对象,用来发送比特用* @param writer 用来发布初始化指定的字符用*/public void DealUpTimer(Socket sender, PrintWriter writer);/*** 处理数据接收* @param data 公共层处理成字符串的数据* @param buf 没处理的比特数组* @param sender Socket对象,用来发送比特用* @param writer 用来发布初始化指定的字符用*/public void DealReceive(String data, byte[] buf, Socket sender, PrintWriter writer);}

然后实现MachSocketBase类作为连接TCP仪器的基础类,里面实现了tcp的客户端和服务端和定时器,里面对数据处理都是调用接口操作

package LIS.Core.Socket;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;import LIS.Core.Socket.IMachDealData;
import LIS.Core.Util.LogUtils;/*** 通过Socket连接的仪器操作基类,由该类提供TCP客户端和服务端的公共逻辑,并且调用处理数据接口处理数据,从而分离TCP主体和业务处理逻辑,达到简化连设备目的*/
public class MachSocketBase {/*** 发送数据的操作对象*/public Socket Sender = null;/*** 写操作对象*/public PrintWriter Writer = null;/*** 主动上传定时器*/public Timer UpTimer = null;/*** 处理接口对象*/public IMachDealData DealObj;/*** 编码*/public String Encode;/*** 要关闭的客户端端口*/private Socket closeSocket = null;/*** 要关闭的服务端口*/private ServerSocket closeServerSocket = null;/*** 存IP和端口的唯一标识串*/public String ID;/*** 处理类的全面*/public String DealClassName;/*** 主处理进程*/Thread MainThread = null;/*** 定时器任务*/TimerTask timerTask = null;/*** 上传间隔*/Long UpPeriod = null;/*** 存启动和停止的错误串*/public String Err="";/*** 停止负载** @return 有错误就返回错误*/public String Stop() {try {if (MainThread != null) {MainThread.interrupt();}if (UpTimer != null) {UpTimer.cancel();}if (closeSocket != null) {closeSocket.close();;}if (closeServerSocket != null) {closeServerSocket.close();;}} catch (Exception ex) {Err=ex.getCause().getMessage();LogUtils.WriteExceptionLog("停止仪器TCP异常", ex);return ex.getCause().getMessage();}return "";}/*** 启动连接和定时器* @return 有错误就返回错误*/public String Start() {try {if (UpTimer != null) {// 设置定时器的执行策略,延迟0秒后开始执行,每隔1秒执行一次UpTimer.schedule(timerTask, 0, UpPeriod);}if (MainThread != null) {MainThread.start();}} catch (Exception ex) {Err=ex.getCause().getMessage();LogUtils.WriteExceptionLog("启动仪器TCP异常", ex);return ex.getCause().getMessage();}return "";}/*** 构造一个Socket基础并且启动Socket** @param ip       IP地址,当服务端传空串* @param port     端口* @param upPeriod 上传毫秒间隔,不是主动上传的传null* @param dealObj  处理接口实现类* @param encode   编码格式,传null或空串默认为GBK*/public MachSocketBase(String ip, int port, Long upPeriod, IMachDealData dealObj, String encode) {//处理对象DealObj = dealObj;//编码if (encode == null || encode.isEmpty()) {encode = "GBK";}Encode = encode;UpPeriod = upPeriod;ID = ip + ":" + port;if(dealObj!=null){DealClassName=dealObj.getClass().getName();}//上传定时器if (upPeriod != null) {UpTimer = new Timer();timerTask = new TimerTask() {@Overridepublic void run() {try {//初始化写对象if (Sender != null && Writer == null) {Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);}DealObj.DealUpTimer(Sender, Writer);} catch (Exception ex) {LogUtils.WriteExceptionLog("仪器上传定时器异常", ex);}}};}//当客户端if (!ip.isEmpty()) {MainThread = new Thread(new Runnable() {@Overridepublic void run() {//得到输入流InputStream inputStream = null;//创建Socket对象并连接到服务端Socket socket = null;try {//创建Socket对象并连接到服务端socket = new Socket(ip, port);Sender = socket;closeSocket = socket;Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);//得到输入流inputStream = socket.getInputStream();//IO读取byte[] buf = new byte[102400];int readlen = 0;//阻塞读取数据while ((readlen = inputStream.read(buf)) != -1) {String res = new String(buf, 0, readlen, Encode);byte[] targetArray = new byte[readlen];System.arraycopy(buf, 0, targetArray, 0, readlen);//处理接收数据DealObj.DealReceive(res, targetArray, Sender, Writer);}} catch (IOException ex) {LogUtils.WriteExceptionLog("侦听仪器TCP异常", ex);} finally {try {if (inputStream != null) {//关闭输入inputStream.close();}if (Writer != null) {Writer.flush();//关闭输出Writer.close();}if (socket != null) {// 关闭连接socket.close();}} catch (Exception ex) {LogUtils.WriteExceptionLog("释放TCP资源异常", ex);}}}});}//当服务端else {MainThread = new Thread(new Runnable() {@Overridepublic void run() {//得到输入流InputStream inputStream = null;//创建Socket对象并连接到服务端Socket socket = null;try {ServerSocket serverSocket = new ServerSocket(port);closeServerSocket = serverSocket;//增加一个无限循环while (true) {//等待客户端连接,阻塞socket = serverSocket.accept();Sender = socket;//得到输出流Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);//得到输入流inputStream = socket.getInputStream();//IO读取byte[] buf = new byte[102400];int readlen = 0;//阻塞读取数据while ((readlen = inputStream.read(buf)) != -1) {String res = new String(buf, 0, readlen, Encode);byte[] targetArray = new byte[readlen];System.arraycopy(buf, 0, targetArray, 0, readlen);//处理接收数据DealObj.DealReceive(res, targetArray, Sender, Writer);}}} catch (IOException ex) {LogUtils.WriteExceptionLog("侦听仪器TCP异常", ex);} finally {try {if (inputStream != null) {//关闭输入inputStream.close();}if (Writer != null) {Writer.flush();//关闭输出Writer.close();}if (socket != null) {// 关闭连接socket.close();}} catch (Exception ex) {LogUtils.WriteExceptionLog("释放TCP资源异常", ex);}}}});}}
}

然后为了统一管理所有TCP仪器提供MachManager,接口开发者之需要关心GetMachSocketBase方法

package LIS.Core.Socket;import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import LIS.Core.Socket.MachSocketBase;
import LIS.Core.Socket.IMachDealData;/*** 统一管理所有仪器的MachSocketBase对象*/
public class MachManager {/*** 存所有仪器连接*/public static ConcurrentHashMap<String, MachSocketBase> AllMach = new ConcurrentHashMap<>();/*** 更新处理接口对象* @param dealClass* @throws Exception*/public static void UpdateDeal(Class dealClass) throws Exception{String dealClsName=dealClass.getName();for (Map.Entry<String, MachSocketBase> entry : AllMach.entrySet()) {String key = entry.getKey();MachSocketBase value = entry.getValue();if(value.DealClassName.equals(dealClsName)){//创建对象Object o = dealClass.getConstructor().newInstance();value.DealObj=(IMachDealData)o;System.out.println("更新:"+value.ID+"的数据处理类");}}}/*** 得到仪器连接的Socket管理类,直接就启动了控制了* @param ip IP地址,当服务端传空串* @param port 端口* @param upPeriod 上传毫秒间隔,不是主动上传的传null* @param dealObj 处理接口实现类* @param encode 编码格式,传null或空串默认为GBK* @return*/public static MachSocketBase GetMachSocketBase(String ip, int port, Long upPeriod, IMachDealData dealObj, String encode){MachSocketBase base=new MachSocketBase(ip,port,upPeriod,dealObj,encode);//注册到管理RegisterMachSocketBase(base);return base;}/*** 注册到管理* @param base*/public static void RegisterMachSocketBase(MachSocketBase base){//先停止老的接口if(AllMach.containsKey(base.ID)){AllMach.get(base.ID).Stop();AllMach.remove(base.ID);}//加入管理AllMach.put(base.ID,base);base.Start();}
}

然后为了解决修改仪器接口脚本后实时生效实现仪器注解,接口修改后会自动调用MachManager.UpdateDeal更新处理类,这样不用频繁重启仪器控制

//特性,申明此特性的仪器接口在修改后自动调用启动
package LIS.Core.CustomAttributes;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 申明此特性的仪器接口在修改后自动调用启动*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface  Mach {}

在这里插入图片描述

然后实现一个实例仪器接口
在这里插入图片描述

import LIS.Core.CustomAttributes.Mach;
import LIS.Core.Socket.IMachDealData;
import LIS.Core.Socket.MachSocketBase;
import appcode.BaseHttpHandlerNoSession;
import appcode.Helper;import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;/***连仪器示例代码*/
@Mach
public class MachDemo extends BaseHttpHandlerNoSession implements IMachDealData {/*** 缓存数据*/private static StringBuilder dataCache=new StringBuilder();//换行符private static String lineStr=System.getProperty("line.separator");/*** 显示日志* http://localhost:8080/ankilis/mi/MachDemo.ashx?Method=ShowLog* @return*/public String ShowLog(){return dataCache.toString();}/*** 启动控制* http://localhost:8080/ankilis/mi/MachDemo.ashx?Method=Start* @return* @throws Exception*/public String Start() throws Exception{//ip地址String ip=Helper.ValidParam(LIS.Core.MultiPlatform.LISContext.GetRequest(Request, "ip"), "");//端口int port=Helper.ValidParam(LIS.Core.MultiPlatform.LISContext.GetRequest(Request, "port"), 8888);MachSocketBase base=LIS.Core.Socket.MachManager.GetMachSocketBase(ip,port,Long.valueOf(5000),this,"GBK");if(base.Err.isEmpty()){return Helper.Success();}else{return Helper.Error(base.Err);}}/*** 处理上传定时器接口* @param sender Socket对象,用来发送比特用* @param writer 用来发布初始化指定的字符用*/public void DealUpTimer(Socket sender, PrintWriter writer){String sendStr="H->M:我主动定时给你推送的数据</br>";//返回数据writer.print(sendStr);writer.flush();dataCache.append(sendStr+lineStr);}/*** 处理数据接收* @param data 公共层处理成字符串的数据* @param buf 没处理的比特数组* @param sender Socket对象,用来发送比特用* @param writer 用来发布初始化指定的字符用*/public void DealReceive(String data, byte[] buf, Socket sender, PrintWriter writer){//缓存数据dataCache.append("M->H:"+data+lineStr);String sendStr="H->M:我收到你发给我的:"+data+"</br>";//返回数据writer.print(sendStr);writer.flush();dataCache.append(sendStr+lineStr);}
}

启动控制
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

这样就可以在这个基础上轻松连接TCP的仪器了,还是脚本化、还不用来回重启控制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/157479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web 自动化神器 TestCafe—页面基本操作篇

前 言 Testcafe是基于node.js的框架&#xff0c;以操作简洁著称&#xff0c;是web自动化的神器 今天主要给大家介绍一下testcafe这个框架和页面元素交互的方法。 一、互动要求 使用 TestCafe 与元素进行交互操作&#xff0c;元素需满足以下条件&#xff1a;☟ 元素在 body 页…

专访特斯拉工程师杨硕:跟着机器人上天入地、探索地外行星丨智源独家

导读 十几岁时&#xff0c;他痴迷《终结者》&#xff0c;曾在百科全书中窥见卡内基梅隆大学机械臂的介绍&#xff0c;从而得知了研究机器人「圣地」的存在。 在CMU&#xff0c;他深耕足式机器人感知定位算法&#xff0c;期待未来涉足太空&#xff0c;走上火星。 在大疆&#xf…

瑞格心理咨询系统设置多个管理员的操作方法

使用瑞格心理咨询系统&#xff0c;需要设置多个admin权限的管理员账号来管理&#xff0c;咨询厂家答复只能有1个管理员&#xff0c;个人觉得不可能&#xff0c;于是开始折腾。 解决办法&#xff1a; 在没有数据字典的情况下&#xff0c; 通过遍历数据库&#xff0c;发现用户信…

『 Linux 』使用fork函数创建进程与进程状态的查看

文章目录 &#x1f5a5;️ 前言 &#x1f5a5;️&#x1f5a5;️ 通过系统调用获取进程标识符 &#x1f5a5;️&#x1f4bb; 进程标识符PID&#x1f4bb; 父进程标识符PPID &#x1f5a5;️ 通过系统调用创建子进程 fork() &#x1f5a5;️&#x1f4bb; 那么为什么在fork()函…

线程池简介及其简单实现

如果需要频繁的创建销毁线程, 就需要想办法降低创建和销毁的开销, 而线程池就是一个很好的选择: 提前创建好一些线程, 等到需要使用线程的时候, 直接从池子里拿一个就好了, 当不再使用该线程时, 就放回到池子里. 那么此时就从 创建/销毁线程 -> 池子里取线程/将线程还到池子…

构建智能医患沟通:陪诊小程序开发实战

在医疗科技的浪潮中&#xff0c;陪诊小程序的开发成为改善医患沟通的创新途径之一。本文将介绍如何使用Node.js和Express框架构建一个简单而强大的陪诊小程序&#xff0c;实现患者导诊和医生咨询功能。 1. 安装Node.js和Express 首先确保已安装Node.js&#xff0c;然后使用以…

Linux procps-ng - top

procps-ng 是一个开源的进程管理工具集&#xff0c;它提供了一系列用于监控和管理系统进程的命令行工具。它是 procps 工具集的一个分支&#xff0c;旨在改进和增强原有的 procps 工具。 procps-ng 包括了一些常用的命令行工具&#xff0c;例如&#xff1a; ps&#xff1a;用于…

机器学习笔记 - 创建CNN + RNN + CTC损失的模型来识别图像中的文本

我们将创建一个具有CTC损失的卷积循环神经网络来实现我们的OCR识别模型。 一、数据集 我们将使用 Visual Geometry Group 提供的数据。 Visual Geometry Group - University of OxfordComputer Vision group from the University of Oxfordhttps://www.robots.ox.ac.uk/~vgg/d…

最新AIGC创作系统ChatGPT系统源码,支持最新GPT-4-Turbo模型,支持DALL-E3文生图,图片对话理解功能

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

leetcode:415. 字符串相加(模拟竖式计算)

一、题目 链接&#xff1a; 415. 字符串相加 - 力扣&#xff08;LeetCode&#xff09; 函数原型&#xff1a;char* addStrings(char* num1, char* num2) 二、思路&#xff1a; 本题本质是将两个字符型数字相加&#xff0c;字符型数字相加就一定需要进行字符与数字的相互转换 详…

秋招JAVA面经总结

面试的范围是Java基础+Java并发+Java框架+mysql+网络。 Java基础 重载与重写有什么区别? 重载(Overloading)指的是在同一个类中,可以有多个同名方法,它们具有不同的参数列表(参数类型、参数个数或参数顺序不同),编译器根据调用时的参数类型来决定调用哪个方法。 重写…

笔试强训2

目录 &#x1f449;&#x1f3fb;字符串反转&#x1f449;&#x1f3fb;公共子串计算 &#x1f449;&#x1f3fb;字符串反转 mycode:100% #include <iostream> #include<algorithm> using namespace std;int main() {string s;cin>>s;reverse(s.begin(),s.…

Java(五)(Object类,克隆,Objects类,包装类,StringBuilder,StringJoiner,BigDecimal)

目录 Object类 Object类的常见方法: 克隆 浅克隆 深克隆 Objects类 包装类 StringBuilder StringJoiner BigDecimal Object类 Object类是java中的祖宗类,因此,Java中所有的类的对象都可以直接使用object类提供的一些方法 Object类的常见方法: public String toStrin…

23111701[含文档+PPT+源码等]计算机毕业设计javaweb点餐系统全套餐饮就餐订餐餐厅

文章目录 **项目功能简介:****点餐系统分为前台和后台****前台功能介绍&#xff1a;****后台功能介绍&#xff1a;** **论文截图&#xff1a;****实现&#xff1a;****代码片段&#xff1a;** 编程技术交流、源码分享、模板分享、网课教程 &#x1f427;裙&#xff1a;77687156…

智能座舱架构与芯片- (8) 视觉篇

一、概述 相比起用于ADAS感知系统的摄像头&#xff0c;用于智能座舱内部的摄像头&#xff0c;其功能特性和性能要求相对简单。例如&#xff0c;OMS乘客监控摄像头&#xff0c;一般达到5MP即可有良好的效果。同时&#xff0c;OMS也可应用于车内会议系统&#xff0c;还应用于车内…

微服务 Spring Cloud 8,开源RPC框架如何选型?

目录 一、开源RPC框架有哪些&#xff1f;1、跟语言平台绑定的开源RPC框架2、跨语言平台的开源RPC框架 二、跟语言平台绑定的开源RPC框架 -- Dubbo1、Dubbo的架构主要包含四个角色2、Dubbo的调用框架是如何实现的&#xff1f; 三、如何选择&#xff1f;四、跨语言平台的开源RPC框…

UI for Apache Kafka

文章Overview of UI Tools for Monitoring and Management of Apache Kafka Clusters | by German Osin | Towards Data Science中介绍了8种常见的kafka UI工具,这些产品的核心功能对比信息如下图所示, 通过对比发现 UI for Apache Kafka 功能齐全且免费,因此可以作为我们的首…

Kubernetes容器状态探测的艺术

在Kubernetes集群中维护容器状态更像是一种艺术&#xff0c;而不是科学。原文: The Art and Science of Probing a Kubernetes Container[1] 在Kubernetes集群中维护容器状态更像是一种艺术&#xff0c;而不是科学。 本文将带你深入理解容器探测[2]&#xff0c;并特别关注相对较…

Linux安装ErLang(亲测可用)

注&#xff08;我这里安装完成后显示的是中文&#xff0c;有的是显示的英文&#xff09; 1.下载er wget https://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm2.安装er yum -y install epel-release截图截不全&#xff0c;就只截安装完成的部分了 rp…

2023年中国语言大模型行业发展趋势分析:预计未来行业将迎来高速增长[图]

自然语言处理&#xff08;NLP&#xff09;大模型是一种利用深度学习技术来理解、解释和生成人类语言的高参数模型。语言大模型通过编码解码的方式模仿人类处理语言的过程从而达到进行自然语言文本输出的能力。 语言大模型主要组成部分 资料来源&#xff1a;共研产业咨询&#…