自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

轉(zhuǎn)轉(zhuǎn)質(zhì)檢桌面應(yīng)用程序的架構(gòu)演進(jìn)

開發(fā) 架構(gòu)
本文對(duì)轉(zhuǎn)轉(zhuǎn)質(zhì)檢的 EJC 架構(gòu)做了一些分享,并給出一些實(shí)踐經(jīng)驗(yàn),希望能為大家解決類似的問題提供一些幫助。目前 EJC 架構(gòu)體系已經(jīng)在質(zhì)檢業(yè)務(wù)中上線了多個(gè)桌面應(yīng)用并穩(wěn)定運(yùn)行,未來將會(huì)覆蓋更多的應(yīng)用場(chǎng)景,助力業(yè)務(wù)得到實(shí)質(zhì)發(fā)展。

質(zhì)檢是轉(zhuǎn)轉(zhuǎn)履約體系中的重要一環(huán),通過對(duì)手機(jī)、平板、筆記本、耳機(jī)、手表等品類商品的軟硬件功能、外觀成色等進(jìn)行全方面檢測(cè),為買家、賣家把好質(zhì)量關(guān),讓二手交易變得更透明、更靠譜,促進(jìn)綠色消費(fèi)。

在質(zhì)檢環(huán)節(jié)中,通過標(biāo)準(zhǔn)化產(chǎn)線,結(jié)合自動(dòng)化設(shè)備、質(zhì)檢 APP、桌面應(yīng)用程序等,最終輸出全面可信的“質(zhì)檢報(bào)告”呈現(xiàn)給用戶。其中,桌面應(yīng)用程序發(fā)揮著舉足輕重的作用,本文將重點(diǎn)介紹桌面應(yīng)用程序架構(gòu)的演進(jìn)及其落地。

1 背景

轉(zhuǎn)轉(zhuǎn)質(zhì)檢的桌面應(yīng)用程序,前期主要由 Qt 構(gòu)建,C/C++提供底層支持。這些桌面應(yīng)用的視圖層、應(yīng)用層、以及底層能力支持,均由 C/C++開發(fā)人員承擔(dān)全部開發(fā)迭代工作。其次隨著業(yè)務(wù)的不斷發(fā)展,部分桌面應(yīng)用程序逐漸暴露出拓展性差、迭代難的問題。

在轉(zhuǎn)轉(zhuǎn)質(zhì)檢技術(shù)團(tuán)隊(duì),除了 C/C++開發(fā)同學(xué)外,還有配套成熟的前端和 Java 后端,綜合來說:對(duì)于視圖層,前端的技術(shù)生態(tài)、以及開發(fā)人員的技術(shù)經(jīng)驗(yàn),在視圖層開發(fā)方面具有很大的優(yōu)勢(shì);在應(yīng)用層方面,Java 技術(shù)生態(tài)的優(yōu)勢(shì)不言而喻,同時(shí) Java 后端同學(xué)對(duì)整體業(yè)務(wù)和系統(tǒng)都有著相對(duì)全面深入的了解,簡(jiǎn)而言之,Java 同學(xué)在應(yīng)用層架構(gòu)設(shè)計(jì)和落地方面,是非常合適的。

綜上,基于團(tuán)隊(duì)實(shí)際,筆者團(tuán)隊(duì)對(duì)桌面應(yīng)用程序,提出了新的技術(shù)架構(gòu)——EJC(Electron、Java、C/C++)。該架構(gòu)的主要優(yōu)勢(shì)在于:

  • 讓 C/C++開發(fā)同學(xué)更偏向于底層能力的研究,發(fā)揮更大的價(jià)值。
  • Electron 本質(zhì)是前端技術(shù)棧,Java 同學(xué)更理解整體業(yè)務(wù),在應(yīng)用層設(shè)計(jì)經(jīng)驗(yàn)方面更擅長(zhǎng);且前端和 Java 資源更容易靈活調(diào)配。
  • Electron 和 Java 本身是跨端的,對(duì)于后續(xù)質(zhì)檢桌面應(yīng)用各端的整合(Windows&Mac),具有不錯(cuò)的優(yōu)勢(shì)。

2 EJC 架構(gòu)

簡(jiǎn)單說,EJC 技術(shù)架構(gòu)即:Electron(視圖層/用戶層),Java(應(yīng)用層),C/C++(基礎(chǔ)能力層)。

圖片

2.1 Electron

Electron 是一個(gè)基于 Chromium 和 Node.js 的框架,一套多端生成 Windows、macOS 和 Linux 的跨平臺(tái)桌面應(yīng)用程序。

  • 本質(zhì)是前端技術(shù)棧,內(nèi)置了 Chromium 內(nèi)核使得應(yīng)用程序具有最新的 web 標(biāo)準(zhǔn),開發(fā)人員可以專注應(yīng)用程序的邏輯和界面設(shè)計(jì),不用再束手束足做瀏覽器兼容性操作。
  • 整包更新和熱更新,使程序保持最新的狀態(tài),類似混合移動(dòng)應(yīng)用(Hybrid APP)的快感。
  • 安全的跨平臺(tái)運(yùn)行環(huán)境,可以有效地降低程序崩潰和系統(tǒng)錯(cuò)誤的機(jī)率,實(shí)現(xiàn)更加可靠和穩(wěn)定的應(yīng)用程序。
  • 豐富的 API 在 C/C++能力的加持下,讓軟硬件結(jié)合更加絲滑,擴(kuò)展能力更進(jìn)一步。

2.2 Java

Java 應(yīng)用層,主要包括:

  • 通訊模塊:提供基于 HTTP、WebSocket 等協(xié)議的通信能力。
  • 底層交互模塊: 封裝了 Java 調(diào)用本地代碼(動(dòng)態(tài)庫)的技術(shù)(JNI/JNA)。
  • 數(shù)據(jù)存儲(chǔ):使用輕量級(jí)數(shù)據(jù)庫 SQLite 來持久化數(shù)據(jù),為數(shù)據(jù)的高可用及容錯(cuò)提供基礎(chǔ)能力。
  • 事件監(jiān)聽:基于 Spring 的事件和監(jiān)聽機(jī)制實(shí)現(xiàn)了基于事件驅(qū)動(dòng)的編程模型,有松耦合、高擴(kuò)展性和可測(cè)試性等優(yōu)點(diǎn)。
  • 業(yè)務(wù)模塊:必要的業(yè)務(wù)邏輯處理。
  • 監(jiān)控模塊:對(duì)客戶端的實(shí)時(shí)運(yùn)行參數(shù)、硬件異常情況等數(shù)據(jù)進(jìn)行記錄,定時(shí)上報(bào)云端。
  • 配置管理:定時(shí)從云端拉取最新的配置,覆蓋本地配置。
  • 調(diào)度策略:根據(jù)設(shè)備的歷史狀態(tài),預(yù)判硬件(如貨架貨位上的 USB 通訊口、USB 集線器等設(shè)備)是否出現(xiàn)故障,當(dāng)判定故障時(shí),可以優(yōu)先調(diào)度其它設(shè)備并將故障信息上報(bào)。

2.3 C/C++

基礎(chǔ)能力層,核心 SDK 的實(shí)現(xiàn)。提供與 Windows、IOS、安卓、相機(jī)、機(jī)械臂等底層通用能力。

基于上述說明,在轉(zhuǎn)轉(zhuǎn)質(zhì)檢中,筆者呈現(xiàn)的 EJC 技術(shù)架構(gòu),如下:

圖片

EJC架構(gòu)圖

下面重點(diǎn)對(duì) Java 應(yīng)用層的前端通訊模塊、底層通訊模塊進(jìn)行介紹。

2.4 前端通訊模塊

在 Java 應(yīng)用層兼容了 HTTP 協(xié)議、WebSocket 協(xié)議的通信方式。接下來介紹幾種與前端通訊的方案以及我們?cè)?EJC 架構(gòu)中的選型和考量:

2.4.1 HTTP 短輪詢

客戶端周期性的向服務(wù)器發(fā)送請(qǐng)求,以獲得最新的數(shù)據(jù),這種方式會(huì)造成服務(wù)器和網(wǎng)絡(luò)資源的浪費(fèi)。適用于實(shí)時(shí)性要求不高的場(chǎng)景:在 Java 客戶端從云端拉取配置時(shí),采用的就是此機(jī)制。

圖片

2.4.2 HTTP 長(zhǎng)輪詢

與 HTTP 短輪詢相比,HTTP 長(zhǎng)輪詢能夠避免客戶端頻繁向服務(wù)器發(fā)送請(qǐng)求,節(jié)省了網(wǎng)絡(luò)和服務(wù)器資源的開銷,同時(shí)能實(shí)現(xiàn)更及時(shí)和可靠的數(shù)據(jù)推送。

圖片

2.4.3 SSE(Server-Sent Events)

本質(zhì)上是一個(gè) HTTP 長(zhǎng)連接,服務(wù)端發(fā)送給客戶端不是一個(gè)數(shù)據(jù)包,而是一個(gè) stream 流,格式為 text/stream,所以客戶端不會(huì)關(guān)閉連接,會(huì)一直等著服務(wù)器發(fā)過來新的數(shù)據(jù)流。適合一些只需要服務(wù)端單向推送事件給客戶端的場(chǎng)景。

圖片

在實(shí)際的應(yīng)用場(chǎng)景中,服務(wù)端只需要推送一次信息給前端(如:前端調(diào)用 Java 服務(wù)端獲取系統(tǒng)硬件配置信息),我們選擇 SSE 作為前后端的通信方式,有以下優(yōu)勢(shì):

  • 比 http 短輪詢性能更好。
  • 比 http 長(zhǎng)輪詢更可靠。
  • 比 WebSocket 更輕量。
  • 可以在現(xiàn)有的基礎(chǔ)設(shè)施和技術(shù)上使用,而不需要進(jìn)行任何額外的配置或部署。

2.4.4 WebSocket

WebSocket 是基于 TCP 的雙向通信協(xié)議,可以實(shí)現(xiàn)實(shí)時(shí)通信。適合實(shí)時(shí)性要求很高而且需要雙工通信的系統(tǒng)。在實(shí)際的應(yīng)用中,如隱私清除工具,從插入手機(jī)到隱私清除完成只需要 3~5 秒,質(zhì)檢人員需要實(shí)時(shí)的看到手機(jī)狀態(tài)的變更,這時(shí)候我們選用 Websocket 實(shí)時(shí)的將數(shù)據(jù)狀態(tài)推送到前端進(jìn)行展示。

圖片

2.5 底層通訊模塊

Java 調(diào)用 C/C++ 有 JNI (Java Native Interface) 與 JNA (Java Native Access) 兩種方式,都是 Java 中用于調(diào)用本地底層 SDK 的技術(shù)。

下面通過簡(jiǎn)單的代碼示例(獲取 IOS 設(shè)備名稱)來說明 Java 是如何調(diào)用底層 SDK 的。為了節(jié)約篇幅,僅展示了部分關(guān)鍵代碼。

2.5.1 JNI 介紹和使用

Java 語言提供的標(biāo)準(zhǔn)接口,它提供了一組函數(shù)和數(shù)據(jù)類型,允許 Java 應(yīng)用程序調(diào)用和被 C/C++ 語言調(diào)用。JNI 通過編寫本地方法實(shí)現(xiàn)與 C/C++ 語言的交互。

  • 使用 native 關(guān)鍵字聲明本地方法。
public class JniDemo {
/**
* 獲取IOS設(shè)備的名稱
* @param udid 設(shè)備UDID
* @return 設(shè)備名稱
*/
public native String getDeviceNameByUDID(String udid);
}
  • 通過 javah 命令,將代碼中的 native 方法生成對(duì)應(yīng)的 C 語言的頭文件。
> javah JniDemo
// JDK10+已經(jīng)移除了javah命令工具,使用以下命令
> javac JniDemo.java -h outputDir
  • 執(zhí)行上述命令后,將生成一個(gè)名為 JniDemo.h 的 C/C++ 頭文件。
#include <jni.h>
/* Header for class JniDemo */

#ifndef _Included_JniDemo
#define _Included_JniDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* 包含了 getDeviceNameByUDID 方法的聲明
* Class: JniDemo
* Method: getDeviceNameByUDID
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniDemo_getDeviceNameByUDID
(JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif
  • C/C++ 實(shí)現(xiàn)頭文件來實(shí)現(xiàn) Java_JniDemo_getDeviceNameByUDID 方法,并將其編譯為動(dòng)態(tài)庫。
#include "jnidemo.h"

JNIEXPORT jstring JNICALL Java_JniDemo_getDeviceNameByUDID(JNIEnv *env, jobject, jstring udid)
{
string udid_cpp = jstringTostring(env, udid);
LHW_INFO("udid_cpp = " << udid_cpp);
IOS_Device_Interface idi;
string device_name = idi.get_device_name_by_udid(udid_cpp);
LHW_INFO("device_name = " << device_name);
return stringTojstring(env, device_name.c_str());
}
  • Java 使用
public class JniDemo {
/**
* 獲取IOS設(shè)備的名稱
* @param udid 設(shè)備UDID
* @return 設(shè)備名稱
*/
public native String getDeviceNameByUDID(String udid);

public static void main(String[] args) {
System.loadLibrary("jniDemo");
JniDemo obj = new JniDemo();
String result = obj.getDeviceNameByUDID("00008110-001518392EE3801E");
System.out.println("Result is " + result);
// Result is iphone 13 pro
}
}

2.5.2 JNA 介紹和使用

JNA 是在 JNI 基礎(chǔ)上實(shí)現(xiàn)的編程框架,實(shí)現(xiàn)了 Java 類型到 C 類型的自動(dòng)轉(zhuǎn)換。Java 開發(fā)人員只要在一個(gè) Java 接口中描述目標(biāo) native library 的函數(shù)與結(jié)構(gòu),不再需要編寫任何 Native/JNI 代碼,極大的降低了 Java 調(diào)用動(dòng)態(tài)庫的開發(fā)難度。

  • 編寫 C/C++代碼,聲明頭文件(需要使用 extern “C”關(guān)鍵字才能被 JNA 調(diào)用)。
#pragma once
#include "pch.h"

#ifndef JNADemoAPI
#define JNADemoAPI __declspec(dllexport)
#endif // !_Included_JnaDemo

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

JNADemoAPI const char* getDeviceNameByUDID(const char *udid);


#ifdef __cplusplus
}
#endif // __cplusplus
  • 實(shí)現(xiàn)頭文件,并將其編譯為動(dòng)態(tài)庫。
#include "pch.h"
#include "JnaDemo.h"
#include "IOSDevice/ios_device_pimpl.h"

string IOS_Device_Interface::getDeviceNameByUDID(string udid) {
return ios_device->get_deviceName_by_udid(udid);
}
  • Java 中使用。

首先在項(xiàng)目中引入 JNA 庫:

<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>jna</artifactId>
<version>5.12.1</version>
</dependency>

聲明與動(dòng)態(tài)庫對(duì)應(yīng)的 Java 接口類:

/**
* 定義動(dòng)態(tài)庫接口
*/
public interface JnaDemo extends Library {
/**
* 與 C/C++ 中的函數(shù)名對(duì)應(yīng)
* @param 設(shè)備UDID
* @return 設(shè)備名稱
*/
String getDeviceNameByUDID(String udid);
}

加載動(dòng)態(tài)庫并調(diào)用方法:

/**
* 通過 JNA 調(diào)用 C/C++ 函數(shù)
*
*/
public class JnaDemoTest {

public static void main(String[] args) {
// 加載名為 jnaDemo 動(dòng)態(tài)庫
JnaDemo jnaDemo = Native.load("JnaDemo", JnaDemo.class);
// 調(diào)用方法并獲取結(jié)果
String result = jnaDemo.getDeviceNameByUDID("00008110-001518392EE3801E");
System.out.println("Result is " + result);
// Result is iphone 13 pro
}
}

2.5.3 選型和考量

通過上述的示例代碼我們對(duì)比了兩種方案的優(yōu)缺點(diǎn),并進(jìn)行了性能測(cè)試。


JNI

JNA

優(yōu)點(diǎn)

本地方法編譯后可以選擇 C 或 C++ 來實(shí)現(xiàn)。調(diào)用本地方法時(shí)效率相對(duì) JNA 高。

封裝了系統(tǒng)常用的動(dòng)態(tài)庫,可以直接使用。開發(fā)效率相對(duì) JNI 高,無需 Java 編寫本地方法。

缺點(diǎn)

開發(fā)效率相對(duì)較低,需要 Java 編寫本地方法并編譯生成 C/C++頭文件,C/C++ 需要按照生成的頭文件進(jìn)行編碼實(shí)現(xiàn)。

不支持 C++編譯生成的動(dòng)態(tài)庫,需要在 C++ 接口的上層用 C 語言進(jìn)行一次封裝。

從開發(fā)者的角度來說:JNA 對(duì) Java 開發(fā)者比較友好,JNI 則對(duì) C/C++開發(fā)者比較友好。

同時(shí)我們分別用 JNI 和 JNA 進(jìn)行 100 次到 500 次讀取 IOS 設(shè)備名稱的性能測(cè)試,得到耗時(shí)對(duì)比。在 8 核 16G 機(jī)器上運(yùn)行得到如下結(jié)果:

計(jì)算數(shù)量(百次)

JNI

JNA

1

1197ms

26957ms

2

2196ms

52800ms

3

2759ms

79260ms

4

4573ms

106377ms

5

6299ms

132482ms

通過上面的對(duì)比和性能測(cè)試,我們制定了如下選型標(biāo)準(zhǔn):

  • 自研的 SDK:高優(yōu)使用 JNI 作為底層通信方式。優(yōu)勢(shì)在于:JNI 的性能更好,底層數(shù)據(jù)交互的接口由 Java 定義,C/C++開發(fā)者可以選擇 C 或 C++進(jìn)行實(shí)現(xiàn),有更多的選擇性及靈活性。
  • 外部廠商提供的 SDK:優(yōu)先調(diào)用廠商自帶的 SDK。優(yōu)勢(shì)在于:無需 C/C++再次封裝一層動(dòng)態(tài)庫,減少開發(fā)資源的投入。

3 EJC 架構(gòu)的落地

EJC 架構(gòu)在轉(zhuǎn)轉(zhuǎn)質(zhì)檢已成功落地了多個(gè)應(yīng)用,下面主要介紹 EJC 在 Windows 筆記本質(zhì)檢工具中的落地。

3.1 項(xiàng)目背景

隨著質(zhì)檢業(yè)務(wù)的發(fā)展,筆記本質(zhì)檢量再創(chuàng)新高。早期由 C/C++開發(fā)、使用 Qt 構(gòu)建的筆記本驗(yàn)機(jī)工具已不能滿足業(yè)務(wù)的需求,主要體現(xiàn)有以下幾點(diǎn):

  • 維護(hù)成本高:代碼的復(fù)雜性較高,維護(hù)需要開發(fā)者投入更多的時(shí)間和精力。
  • 覆蓋率低:功能不夠完善,易用性較差,使用覆蓋率低。
  • 移植性差:無法移植到 Mac 平臺(tái)。

基于上述的項(xiàng)目背景,我們使用了 EJC 架構(gòu)來重構(gòu)筆記本驗(yàn)機(jī)工具。

3.2 架構(gòu)實(shí)現(xiàn)

3.2.1 名詞解釋

  • WMI:Windows Management Instrumentation;是 Windows 系統(tǒng)標(biāo)準(zhǔn)的信息服務(wù)。
  • WinAPI:Windows 系統(tǒng)提供的底層接口。
  • DLL(C):即 EJC 中的 C,由我們 C/C++的同學(xué)研發(fā)的底層 SDK。

3.2.2 流程描述

  • 錄入獲取數(shù)據(jù)流程:Electron 啟動(dòng)后 -> 后臺(tái)異步啟動(dòng) Java 服務(wù)端 -> 開啟異步全局掃描筆記本基本數(shù)據(jù)項(xiàng)注解 -> 獲得需讀取的電腦屬性 -> 調(diào)度器分類執(zhí)行屬性獲取命令 -> 執(zhí)行獲取命令執(zhí)行鏈(可橫向擴(kuò)展獲取方式)-> 數(shù)據(jù)加工 -> 數(shù)據(jù)糾錯(cuò) -> 經(jīng) SSE 通道推送頁面渲染。
  • 質(zhì)檢流程輔助流程:進(jìn)入質(zhì)檢流程 -> 請(qǐng)求質(zhì)檢項(xiàng)輔助(某個(gè)功能,例如指紋是否正常)-> Java 調(diào)用底層(Dll、Wmi 等其他方式)-> 返回輔助質(zhì)檢結(jié)果 -> 頁面回傳渲染質(zhì)檢項(xiàng)支持結(jié)果。

3.2.3 流程釋義

  • 執(zhí)行鏈:考慮到電腦某項(xiàng)屬性需要多種方式獲取并互相就糾正,因此可以針對(duì)性的配置其特有的執(zhí)行鏈,以達(dá)到更好的讀取準(zhǔn)確率,也更加方便擴(kuò)展。
  • 數(shù)據(jù)糾錯(cuò):某些屬性比如電池健康值;默認(rèn)采取 WMI 讀取;但是部分廠商沒有按照 WMI 的標(biāo)準(zhǔn)寫值,導(dǎo)致獲取為空;因此需要調(diào)取 DLL(C)的其他獲取方式作為補(bǔ)充。

3.3 項(xiàng)目呈現(xiàn)

3.3.1 錄入模塊

通過 Java、C/C++讀取筆記本關(guān)鍵信息,獲取筆記本基本情況。通過錄入功能,輔助一線人員選擇系統(tǒng)標(biāo)品項(xiàng),同時(shí)與質(zhì)檢碼進(jìn)行關(guān)聯(lián)入庫。在此基礎(chǔ)上產(chǎn)生原始信息與標(biāo)品 ID 的映射關(guān)系,減少下次相同機(jī)型的一個(gè)操作步驟,方便一線操作人員在質(zhì)檢相同機(jī)型的一個(gè)操作便攜性。

圖片

筆記本錄入模塊

3.3.2 質(zhì)檢模塊

通過品牌機(jī)型獲取系統(tǒng)對(duì)應(yīng)的質(zhì)檢模版,提供自動(dòng)&輔助質(zhì)檢能力,協(xié)助一線質(zhì)檢人員對(duì)筆記本的質(zhì)檢能力更快捷、精準(zhǔn)。

圖片

4 總結(jié)

本文對(duì)轉(zhuǎn)轉(zhuǎn)質(zhì)檢的 EJC 架構(gòu)做了一些分享,并給出一些實(shí)踐經(jīng)驗(yàn),希望能為大家解決類似的問題提供一些幫助。目前 EJC 架構(gòu)體系已經(jīng)在質(zhì)檢業(yè)務(wù)中上線了多個(gè)桌面應(yīng)用并穩(wěn)定運(yùn)行,未來將會(huì)覆蓋更多的應(yīng)用場(chǎng)景,助力業(yè)務(wù)得到實(shí)質(zhì)發(fā)展。

5 參考鏈接

責(zé)任編輯:武曉燕 來源: 轉(zhuǎn)轉(zhuǎn)技術(shù)
相關(guān)推薦

2024-06-13 07:51:08

2009-07-17 16:09:29

Swing桌面應(yīng)用程序

2010-07-15 11:34:13

應(yīng)用虛擬化桌面虛擬化基礎(chǔ)架構(gòu)

2020-10-10 10:30:31

JavaScript開發(fā)技術(shù)

2023-02-01 10:11:06

轉(zhuǎn)轉(zhuǎn)容器日志

2011-03-16 11:04:15

數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)重點(diǎn)信息架構(gòu)

2024-08-29 14:44:01

質(zhì)檢埋點(diǎn)

2010-01-04 10:41:14

Silverlight

2011-08-10 11:25:59

ipad信息架構(gòu)數(shù)據(jù)結(jié)構(gòu)

2020-05-12 10:06:52

JavaScript開發(fā)框架

2017-01-10 08:30:01

2011-07-22 14:08:19

iPad 架構(gòu) 數(shù)據(jù)

2023-01-09 17:04:24

2015-02-02 15:46:59

Web應(yīng)用架構(gòu)大數(shù)據(jù)

2019-02-18 15:20:57

微軟瀏覽器Windows

2021-08-23 09:00:00

架構(gòu)開發(fā)技術(shù)

2023-07-12 08:33:34

引擎LiteFlow編排

2011-12-23 10:01:29

2024-02-29 08:32:03

HTTP協(xié)議Web服務(wù)消息隊(duì)列

2020-09-23 14:33:01

Golang桌面開發(fā)GUI
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)