【開發指南】HTML和JS編寫多用戶VR應用程序的框架

1.概述

Networked-Aframe 的工作原理是將實體及其組件同步到連接的用戶。要連接到房間,您需要將networked-scene組件添加到a-scene元素。對于要同步的實體,請向其添加networked組件。默認情況下,positionrotation組件是同步的,但如果您想同步其他組件或子組件,則需要定義架構。有關網絡消息的更高級控制,請參閱廣播自定義消息和選項部分。

2.場景組件

A-Frame<a-scene>上的組件。

<a-scene networked-scene="serverURL: /;app: <appId>;room: <roomName>;connectOnLoad: true;onConnect: onConnect;adapter: wseasyrtc;audio: false;video: false;debug: false;
">...
</a-scene>

屬性

描述

默認值

serverURL

選擇 WebSocket/信令服務器所在的位置。

/

app

唯一的應用程序名稱。不允許有空格。

default

room

獨特的房間名稱。每個應用程序可以有多個。不允許有空格。每個應用程序可以有多個房間,客戶端只能連接到同一應用程序和房間中的客戶端。

default

connectOnLoad

網頁加載后立即連接到服務器。

true

onConnect

當客戶端成功連接到服務器時調用的函數。

onConnect

adapter

您要使用的網絡服務,請參閱適配器。

wseasyrtc

audio

打開/關閉您的應用程序的麥克風音頻流。僅當所選適配器支持時才有效。

false

video

打開/關閉您的應用程序的視頻流。僅當所選適配器支持時才有效。

false

debug

打開/關閉 Networked-Aframe 調試日志。

false

3.連接

默認情況下,networked-scene將自動連接到您的服務器。為了防止這種情況發生并控制何時連接,請在networked-scene中將connectOnLoad設置為 false。當您準備好連接時,會在a-scene元素上發出connect事件。

AFRAME.scenes[0].emit('connect');

4.斷開連接

要斷開連接,只需從a-scene元素中刪除networked-scene組件即可。

AFRAME.scenes[0].removeAttribute('networked-scene');

從頁面中完全刪除a-scene也可以徹底斷開連接。

5.創建網絡實體

<a-assets><template id="my-template"><a-entity><a-sphere color="#f00"></a-sphere></a-entity></template>
</a-assets><!-- Attach local template by default -->
<a-entity networked="template: #my-template">
</a-entity><!-- Do not attach local template -->
<a-entity networked="template:#my-template;attachTemplateToLocal:false">
</a-entity>

創建要在客戶端之間同步的模板實例。默認情況下,位置和旋轉將同步。buffered-interpolation庫用于允許更少的網絡更新,同時保持平滑的運動。

模板只能有一個根元素。當attachTemplateToLocal設置為true時,該元素上的屬性將被復制到本地實體,并且子元素將被附加到本地實體。遠程實例化的實體將是模板根元素的副本,并添加了networked組件。

(1)attachTemplateToLocal=true示例

<a-entity wasd-controls networked="template:#my-template">
</a-entity><!-- Locally instantiated as: -->
<a-entity wasd-controls networked="template:#my-template"><a-sphere color="#f00"></a-sphere>
</a-entity><!-- Remotely instantiated as: -->
<a-entity networked="template:#my-template;networkId:123;"><a-sphere color="#f00"></a-sphere>
</a-entity>

(2)attachTemplateToLocal=false示例

<a-entity wasd-controls networked="template:#my-template;attachTemplateToLocal:false;">
</a-entity><!-- No changes to local entity on instantiation --><!-- Remotely instantiated as: -->
<a-entity networked="template:#my-template;networkId:123;"><a-sphere color="#f00"></a-sphere>
</a-entity>
 

屬性

描述

默認值

template

存儲在<a-assets>中的模板標簽的 css 選擇器

''”

attachTemplateToLocal

設置為 false 時,不附加本地用戶的模板。當本地和遠程存在不同行為時,這非常有用。

true

persistent

在遠程創建者(而非所有者)斷開連接時,嘗試獲取持久實體的所有權而不是刪除它們

false

6.刪除網絡實體

目前只有網絡實體的創建者可以刪除它。要刪除,只需使用常規 DOM API 從 HTML 中刪除元素,Networked-Aframe 將自動處理同步。

7.同步自定義組件

默認情況下,根實體上的positionrotation組件是同步的。

要同步其他組件和子實體的組件,您需要為每個模板定義一個架構。以下是定義和添加架構的方法:

NAF.schemas.add({template: '#avatar-template',components: ['position','rotation','scale',{selector: '.hairs',component: 'show-child'},{selector: '.head',component: 'material',property: 'color'},]
});

根實體的組件可以用組件的名稱來定義。子實體的組件可以使用具有selector字段和component字段的對象來定義,該字段使用document.querySelector使用的標準 CSS 選擇器它指定組件的名稱。要僅同步多屬性組件的一個屬性,請添加帶有屬性名稱的property字段。

定義架構后,通過調用NAF.schemas.add(YOUR_SCHEMA)將其添加到架構列表中。

組件數據由 A-Frame 組件data屬性檢索。在網絡更新期間,每個組件的數據都會根據其之前的同步值進行檢查;如果數據對象發生了任何變化,它將通過網絡同步。

8.同步組件優化

對于每個組件,您可以定義一個requiresNetworkUpdate函數,該函數采用當前值,如果當前值較之前值發生更改,則返回 true。如果當前值和先前值足夠接近,您可以返回 false,以免將此更改發送給其他參與者。

默認情況下,當您未定義它時,它始終使用defaultRequiresUpdate函數(在networked.js頂部定義),該函數使用通用deepEqual函數來將當前值與前一個值進行比較,當兩個值不同時使用cachedData = AFRAME.utils.clone(newData);以保留前一個值以供下次比較。AFRAME.utils.clone實現正做JSON.parse(JSON.stringify(obj)),可以與任何類型一起使用,但這可能不是 Vector3 類型(如位置、旋轉、縮放)的最佳性能實現。

只是為了讓你知道這是在做什么:

> const v = new THREE.Vector3(1,2,3);
Vector3 {x: 1, y: 2, z: 3}
> JSON.parse(JSON.stringify(v))
{x: 1, y: 2, z: 3}

因此,如果值發生變化,每次同步過程完成時都會在內存中創建一個新對象,這些對象會在某一時刻被垃圾收集。如果場景很重,垃圾收集通常可能需要 1 毫秒或更長的時間,結果可能是瀏覽器丟掉一些幀,因此沒有一致的 fps。您可以使用 Chrome 分析器來確認這一點。對于移動的頭像來說,這一點幾乎不會被注意到,但如果用戶擁有大量連續移動的對象,這對于您的用例可能很重要。

此外,使用當前的 aframewasd-controls實現以及位置平滑方式,在用戶停止按鍵后 2 秒,玩家位置的變化仍然低于毫米精度,因此通過網絡發送大量 NAF 消息視覺上不易察覺的位置變化。 NAF 已經包含位置插值來平滑接收到的位置變化,因此通過網絡發送所有這些位置變化甚至是多余的。

您可以使用專用函數來比較給定精度的兩個 Vector3,通過避免創建新對象,通過網絡和內存發送更少的消息來實現更好的性能:

const vectorRequiresUpdate = epsilon => {return () => {let prev = null;return curr => {if (prev === null) {prev = new THREE.Vector3(curr.x, curr.y, curr.z);return true;} else if (!NAF.utils.almostEqualVec3(prev, curr, epsilon)) {prev.copy(curr);return true;}return false;};};
};

這個函數實際上是在NAF.utils.vectorRequiresUpdate中定義的,供你使用。

要在網絡模式中使用它以獲得 1 毫米的位置精度和 0.5 度的旋轉精度,請按如下方式使用:

{template: '#avatar-template',components: [{component: 'position',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)},{component: 'rotation',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)}]
}

從0.11.0版本開始,同步位置和旋轉的默認模式使用上述優化。

9.同步嵌套模板 - 例如:手

要同步嵌套模板,請像這樣設置 HTML 節點:

<a-entity id="player" networked="template:#player-template;attachTemplateToLocal:false;" wasd-controls><a-entity camera look-controls networked="template:#head-template;attachTemplateToLocal:false;"></a-entity><a-entity hand-controls="hand:left" networked="template:#left-hand-template"></a-entity><a-entity hand-controls="hand:right" networked="template:#right-hand-template"></a-entity>
</a-entity>

在此示例中,頭部/攝像頭、控制器的左手和右手將生成自己的模板,這些模板將獨立于根玩家進行聯網。注意:這與當前不支持的手部追蹤無關。這種父子關系僅在一個級別之間有效,即。子實體的直接父實體必須具有networked組件。

您需要自己定義左手和右手模板,以便向其他用戶顯示手部模型。只有位置和旋轉會同步給其他用戶。要同步手勢,請參閱下面的networked-hand-controls組件。

10.帶同步手勢的跟蹤控制器

這是比上述更簡單的替代方案。 NAF 允許輕松添加其他人可見的手部模型,這些模型顯示與觸摸的按鈕相匹配的模擬手勢(不是手部跟蹤),這樣您就可以向房間里的其他人指向并豎起大拇指或握拳。

您所要做的就是使用內置的networked-hand-controls組件,將這兩個實體添加為相機裝備的子級:

<a-entityid="my-tracked-left-hand"networked-hand-controls="hand:left"networked="template:#left-hand-default-template"
></a-entity>
<a-entityid="my-tracked-right-hand"networked-hand-controls="hand:right"networked="template:#right-hand-default-template"
></a-entity

您可以設置的公共架構屬性有:

屬性

描述

默認值

取值范圍

color

將被設置為材質顏色

white

hand

指定實體是用于左手還是右手

left

left, right

handModelStyle

A-Frame中可用的內置模型

highPoly

highPoly, lowPoly, toon, controller

customHandModelURL

可選的自定義手模型網址

請注意“控制器”選項——它將使用控制器本身的模型,根據您的平臺自動正確設置——它還將廣播模型支持的按鈕網格更新。 (不幸的是,Quest 2 模型按鈕網格目前存在一個錯誤,因此不會顯示任何更新。)

networked-hand-controls正在完全替換hand-controls,不要同時使用兩者。如果您使用如上所述的網絡組件,則無需為每只手定義模板和網絡架構。默認模板和網絡模式已定義如下:

<template id="left-hand-default-template"><a-entity networked-hand-controls="hand:left"></a-entity>
</template>
<template id="right-hand-default-template"><a-entity networked-hand-controls="hand:right"></a-entity>
</template>
NAF.schemas.add({template: '#left-hand-default-template',components: [{component: 'position',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)},{component: 'rotation',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)},'networked-hand-controls']
});
NAF.schemas.add({template: '#right-hand-default-template',components: [{component: 'position',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)},{component: 'rotation',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)},'networked-hand-controls']
});

11.發送自定義消息

NAF.connection.subscribeToDataChannel(dataType, callback)
NAF.connection.unsubscribeToDataChannel(dataType)NAF.connection.broadcastData(dataType, data)
NAF.connection.broadcastDataGuaranteed(dataType, data)NAF.connection.sendData(clientId, dataType, data)
NAF.connection.sendDataGuaranteed(clientId, dataType, data)

訂閱和取消訂閱dataType指定的網絡消息的回調。使用broadcastData功能向房間內的所有客戶端廣播數據。要僅發送到特定客戶端,請改用sendData函數。

參數

描述

clientId

將此數據發送到的 ClientId

dataType

用于標識網絡消息的字符串。u(更新)、um(UpdateMulti)和r(刪除)是保留數據類型,請不要使用它們

callback

收到類型dataType的消息時調用的函數。參數:function(senderId, dataType, data, targetObj)使用 easyrtc 適配器,targetObj在廣播消息時可以是{targetRoom: 'roomId'},或者在向特定參與者發送消息時可以是{targetEasyrtcid: 'targetId'}。對于 janus 適配器,senderId 始終為 null,并且targetObj更多的是source參數,通常等于“janus-event”。

data

要發送給所有其他客戶端的對象

12.轉讓實體所有權

實體的所有者負責同步其組件數據。當用戶想要修改另一個用戶的實體時,他們必須首先獲得該實體的所有權。所有權轉移示例和切換所有權組件展示了如何獲取實體的所有權并更新它。

NAF.utils.takeOwnership(entityEl)

取得實體的所有權。

NAF.utils.isMine(entityEl)

檢查您是否擁有指定實體。

13.事件

當 NAF 中發生某些事情時,事件就會被觸發。要訂閱這些事件,請遵循以下模式:

document.body.addEventListener('clientConnected', function (evt) {console.error('clientConnected event. clientId =', evt.detail.clientId);
});

創建document.body元素后需要訂閱事件。這可以通過等待document.bodyonLoad方法或使用 NAF 的onConnect函數來實現。使用 NAF 活動演示作為示例。

事件列表:

事件

描述

取值范圍

clientConnected

當另一個客戶端連接到您時觸發

evt.detail.clientId- 連接客戶端的ClientId

clientDisconnected

當另一個客戶端與您斷開連接時觸發

evt.detail.clientId- 斷開連接的客戶端的ClientId

entityCreated

創建網絡實體時觸發

evt.detail.el- 新實體

entityRemoved

刪除網絡實體時觸發

evt.detail.networkId- 已刪除實體的網絡ID

以下事件在networked組件上觸發。有關示例,請參閱切換所有權組件。

所有權轉讓事件列表:

事件

描述

參數范圍

ownership-gained

當網絡實體的所有權被奪取時觸發

evt.detail.el- 獲得所有權的實體

evt.detail.oldOwner- 前任所有者的 clientId

ownership-lost

當網絡實體的所有權丟失時觸發

evt.detail.el- 失去所有權的實體

evt.detail.newOwner- 新所有者的 clientId

ownership-changed

當網絡實體的所有權更改時觸發

evt.detail.el- 失去所有權的實體

evt.detail.oldOwner- 前任所有者的 clientId

evt.detail.newOwner- 新所有者的 clientId

14.適配器

NAF 可與多個網絡庫和服務一起使用。適配器是一個向 NAF 添加對庫的支持的類。如果您只是在開發一個小項目或概念驗證,那么您可能會使用默認配置,并且可以跳過本節。評估不同適配器時應考慮的因素包括:

  • 一間房間需要支持多少個并發用戶?

  • 您想托管自己的服務器嗎?或者像 Firebase 這樣的“無服務器”解決方案可以完成這項工作嗎?

  • 您需要音頻(麥克風)流嗎?

  • 您需要自定義服務器端邏輯嗎?

  • 您想要 WebSocket(客戶端-服務器)網絡架構還是 WebRTC(點對點)網絡架構?

默認情況下使用wseasyrtc適配器,它不支持音頻并使用 TCP 連接。這對于生產部署來說并不理想,但是由于 WebRTC 固有的連接問題,我們將其設置為默認值。要通過 WebRTC 支持音頻,請確保服務器使用 https 并將適配器更改為easyrtc(這使用 UDP)。

支持的適配器列表:

適配器

描述

音頻/視頻支持情況

基于WebSocket 或 WebRTC

如何啟動

wseasyrtc

默認 - 使用 open-easyrtc 庫

No

WebSocket

npm run dev

easyrtc

使用 open-easyrtc 庫

音頻和視頻(相機和屏幕共享)

WebRTC

npm run dev

janus

使用 Janus WebRTC 服務器和 janus-plugin-sfu

音頻和視頻(相機或屏幕共享)

WebRTC

參閱 naf-janus-adapter

socketio

無需外部庫的 SocketIO 實現(服務器支持房間實例化)

No

WebSocket

npm run dev-socketio

webrtc

無需外部庫的原生 WebRTC 實現(正在進行中,目前沒有維護者)

音頻

WebRTC

npm run dev-socketio

Firebase

用于 WebRTC 信號傳輸的 Firebase(目前沒有維護者)

No

WebRTC

參閱 naf-firebase-adapter

uWS

uWebSockets 的實現(目前沒有維護者)

No

WebSocket

參閱 naf-uws-adapter

表中的 WebRTC 表示組件更新使用 WebRTC 數據通道 (UDP),而不是 WebSocket (TCP)。您仍然有一個用于信令部分的 WebSocket。

更為詳細比較,請參閱文檔 NAF 適配器比較。

15.音頻

audio: true添加到networked-scene組件(并使用支持它的適配器)后,默認情況下您將聽不到任何音頻。盡管音頻將進行流式傳輸,但在創建具有networked-audio-source的實體之前,它是聽不到的。來自該實體所有者的音頻將從該實體的位置在 3D 空間中發出。networked-audio-source組件必須與networked組件一起添加到實體(或實體的子實體)。

要使麥克風靜音/取消靜音,您可以使用以下 API(easyrtc 和 janus 適配器):

NAF.connection.adapter.enableMicrophone(enabled)

其中enabledtruefalse

16.視頻

video: true(janus 適配器不需要)添加到networked-scene組件(并使用支持它的適配器)后,默認情況下您將看不到任何視頻。盡管視頻將進行流式傳輸,但在創建使用帶有networked-video-source的網格(例如<a-plane>)的實體之前,它是不可見的。來自該實體所有者的視頻將在 3D 空間中從該實體的位置可見。networked-video-source組件必須添加到具有networked組件的實體的<a-plane>子實體中。

目前,這僅適用于支持getMediaStream(clientId, type="video")API 的 easyrtc 和 janus 適配器。

請參閱,該示例顯示了沒有音頻的用戶攝像頭。

要禁用/重新啟用相機,您可以使用以下 API(僅限 easyrtc 適配器):

NAF.connection.adapter.enableCamera(enabled)

其中enabledtruefalse

使用 easyrtc 適配器,您可以使用addLocalMediaStreamremoveLocalMediaStreamAPI 添加額外的視頻軌道,例如屏幕共享:

navigator.mediaDevices.getDisplayMedia().then((stream) => {NAF.connection.adapter.addLocalMediaStream(stream, "screen");
});NAF.connection.adapter.removeLocalMediaStream("screen");

請參閱多流示例,該示例使用帶有networked-video-source="streamName: screen"的第二個平面向其他參與者顯示屏幕共享。請務必查看此示例 html 文件末尾的注釋以了解已知問題。

17.雜項

NAF.connection.isConnected()

如果已與信令服務器建立連接,則返回 true。

NAF.connection.getConnectedClients()

返回當前連接的客戶端列表。

18.選項

NAF.options.updateRate

每秒調用網絡組件sync函數的頻率。對于大多數社交 VR 應用程序來說,10-20 是正常的。默認為15

NAF.options.useLerp

默認情況下,當創建實體時,buffered-interpolation庫用于平滑位置、旋轉和縮放網絡更新。如果您不希望在創建時使用此功能,請將其設置為 false。

19.離線使用

NAF 已經包含 easyrtc,因此運行npm run dev將提供完全有效的解決方案,而無需訪問外部服務器。不過,這些示例確實依賴于 AFrame 和其他未與 NAF 打包的依賴項。因此,必須首先使 AFrame 適應離線工作,然后對所有其他組件執行相同的操作。這基本上可以歸結為下載所使用的腳本及其內容,例如 3D 模型、字體等資產。建議在網絡控制臺打開時加載頁面并識別哪些請求來自主機外部。

對于 VR,您還需要 https,因為瀏覽器需要它才能實現沉浸式模式。server/easyrtc-server.js文件中提供了說明。也就是說,您必須生成密鑰和證書,將它們添加到本地 CA,然后通過 NAF 提供的 Express 服務器加載它們。確保在server/easyrtc-server.js頂部正確配置,并按照說明通過https.createServer進一步向下啟用 https 本身。一旦您連接到 VR 中的 NAF 服務器,瀏覽器仍然會抱怨證書未知。您可以單擊高級并繼續。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/46151.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/46151.shtml
英文地址,請注明出處:http://en.pswp.cn/web/46151.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

同三維T80004解碼器視頻使用操作說明書:高清HDMI解碼器,高清SDI解碼器,4K超清HDMI解碼器,雙路4K超高清解碼器

同三維T80004解碼器視頻使用操作說明書&#xff1a;高清HDMI解碼器&#xff0c;高清SDI解碼器&#xff0c;4K超清HDMI解碼器&#xff0c;雙路4K超高清解碼器 同三維T80004解碼器系列視頻使用操作說明書&#xff1a;高清HDMI解碼器&#xff0c;高清SDI解碼器&#xff0c;4K超清H…

未來的社交標桿:如何通過AI讓Facebook更加智能化?

在當今信息爆炸的時代&#xff0c;社交媒體平臺的智能化已成為提高用戶體驗和互動質量的關鍵因素。Facebook&#xff0c;作為全球最大的社交平臺之一&#xff0c;通過人工智能&#xff08;AI&#xff09;的廣泛應用&#xff0c;正不斷推進其智能化進程。本文將探討Facebook如何…

CAS的原理

CAS&#xff08;Compare-And-Swap 或 Compare-And-Set&#xff09;是一種用于實現并發編程中無鎖&#xff08;lock-free&#xff09;數據結構的原子操作。CAS 操作比較內存中的某個位置的當前值是否等于預期值&#xff0c;如果相等&#xff0c;則將其更新為新的值&#xff0c;否…

代碼隨想錄學習 54day 圖論 from代碼隨想錄

圖論總結篇 從深搜廣搜 到并查集&#xff0c;從最小生成樹到拓撲排序&#xff0c; 最后是最短路算法系列。至此算上本篇&#xff0c;一共30篇文章&#xff0c;圖論之旅就在此收官了。在0098.所有可達路徑 &#xff0c;我們接觸了兩種圖的存儲方式&#xff0c;鄰接表和鄰接矩陣…

B樹(B-Tree)數據結構

1. 什么是B樹&#xff1f; B樹&#xff08;B-Tree&#xff09;是一種多路搜索樹&#xff0c;用于存儲和檢索大量數據。它是自適應的&#xff0c;適用于各種存儲設備和各種數據量。B樹的特點是高效的搜索、插入和刪除操作&#xff0c;且可以在各種情況下保持樹的平衡。 2. B樹…

昇思25天學習打卡營第16天 | Vision Transformer圖像分類

昇思25天學習打卡營第16天 | Vision Transformer圖像分類 文章目錄 昇思25天學習打卡營第16天 | Vision Transformer圖像分類Vision Transform&#xff08;ViT&#xff09;模型TransformerAttention模塊Encoder模塊 ViT模型輸入 模型構建Multi-Head Attention模塊Encoder模塊Pa…

工業三防平板助力工廠生產數據實時管理

在當今高度數字化和智能化的工業生產環境中&#xff0c;工業三防平板正逐漸成為工廠實現生產數據實時管理的得力助手。這種創新的技術設備不僅能夠在惡劣的工業環境中穩定運行&#xff0c;還為工廠的生產流程優化、效率提升和質量控制帶來了前所未有的機遇。 工業生產場景通常充…

機器學習——數據預處理和特征工程(sklearn)

目錄 一、數據挖掘流程 1. 獲取數據 2. 數據預處理 3. 特征工程 4. 建模&#xff0c;測試模型并預測出結果 5. 驗證模型效果 二、sklearn中的相關包 1.sklearn.preprocessing 2.sklearn.Impute 3.sklearn.feature_selection 4.sklearn.decomposition 三、數據預處理…

【網絡安全】PostMessage:分析JS實現XSS

未經許可&#xff0c;不得轉載。 文章目錄 前言示例正文 前言 PostMessage是一個用于在網頁間安全地發送消息的瀏覽器 API。它允許不同的窗口&#xff08;例如&#xff0c;來自同一域名下的不同頁面或者不同域名下的跨域頁面&#xff09;進行通信&#xff0c;而無需通過服務器…

【Arduino IDE】安裝及開發環境、ESP32庫

一、Arduino IDE下載 二、Arduino IDE安裝 三、ESP32庫 四、Arduino-ESP32庫配置 五、新建ESP32-S3N15R8工程文件 樂鑫官網 Arduino官方下載地址 Arduino官方社區 Arduino中文社區 一、Arduino IDE下載 ESP-IDF、MicroPython和Arduino是三種不同的開發框架&#xff0c;各自適…

定制開發AI智能名片商城微信小程序在私域流量池構建中的應用與策略

摘要 在數字經濟蓬勃發展的今天&#xff0c;私域流量已成為企業競爭的新戰場。定制開發AI智能名片商城微信小程序&#xff0c;作為私域流量池構建的創新工具&#xff0c;正以其獨特的優勢助力企業實現用戶資源的深度挖掘與高效轉化。本文深入探討了定制開發AI智能名片商城微信…

.NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 簡介及區別

簡述 在軟件開發的宇宙中&#xff0c;.NET是一個不斷擴展的星系&#xff0c;每個版本都像是一顆獨特的星球&#xff0c;擁有自己的特性和環境。作為技術經理&#xff0c;站在選擇的十字路口&#xff0c;您需要一張詳盡的星圖來導航。本文將作為您的向導&#xff0c;帶您穿越從.…

AIoTedge智能物聯網邊緣計算平臺:引領未來智能邊緣技術

引言 隨著物聯網技術的飛速發展&#xff0c;我們正步入一個萬物互聯的時代。AIoTedge智能物聯網邊緣計算平臺&#xff0c;以其創新的邊云協同架構&#xff0c;為智能設備和系統提供了強大的數據處理和智能決策能力&#xff0c;開啟了智能物聯網的新篇章。 智能邊緣計算平臺的核…

LLaMA-Factory

文章目錄 一、關于 LLaMA-Factory項目特色性能指標 二、如何使用1、安裝 LLaMA Factory2、數據準備3、快速開始4、LLaMA Board 可視化微調5、構建 DockerCUDA 用戶&#xff1a;昇騰 NPU 用戶&#xff1a;不使用 Docker Compose 構建CUDA 用戶&#xff1a;昇騰 NPU 用戶&#xf…

【Java項目筆記】01項目介紹

一、技術框架 1.后端服務 Spring Boot為主體框架 Spring MVC為Web框架 MyBatis、MyBatis Plus為持久層框架&#xff0c;負責數據庫的讀寫 阿里云短信服務 2.存儲服務 MySql redis緩存數據 MinIO為對象存儲&#xff0c;存儲非結構化數據&#xff08;圖片、視頻、音頻&a…

推薦一款處理TCP數據的架構--EasyTcp4Net

EasyTcp4Net是一個基于c# Pipe,ReadonlySequence的高性能Tcp通信庫,旨在提供穩定,高效,可靠的tcp通訊服務。 基礎的消息通訊 重試機制 超時機制 SSL加密通信支持 KeepAlive 流量背壓控制 粘包和斷包處理 (支持固定頭處理,固定長度處理,固定字符處理) 日志支持Pipe &…

Spring MVC 的常用注解

RequestMapping 和 RestController注解 上面兩個注解&#xff0c;是Spring MCV最常用的注解。 RequestMapping &#xff0c; 他是用來注冊接口的路由映射。 路由映射&#xff1a;當一個用戶訪問url時&#xff0c;將用戶的請求對應到某個方法或類的過程叫做路由映射。 Reques…

定制QCustomPlot 帶有ListView的QCustomPlot 全網唯一份

定制QCustomPlot 帶有ListView的QCustomPlot 文章目錄 定制QCustomPlot 帶有ListView的QCustomPlot摘要需求描述實現關鍵字: Qt、 QCustomPlot、 魔改、 定制、 控件 摘要 先上效果,是你想要的,再看下面的分解,順便點贊搜藏一下;不是直接右上角。 QCustomPlot是一款…

基于springboot+vue+uniapp的駕校預約平臺小程序

開發語言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服務器&#xff1a;tomcat7數據庫&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;數據庫工具&#xff1a;Navicat11開發軟件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

認識AOP--小白可看

AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面編程&#xff09;是一種軟件開發范式&#xff0c;旨在通過橫切關注點&#xff08;cross-cutting concerns&#xff09;的方式來解耦系統中的各個模塊。橫切關注點指的是那些不屬于業務邏輯本身&#xff0c;但是…