欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

基于聲網(wǎng)Flat實(shí)現(xiàn)“成語(yǔ)解謎”的Web小游戲-創(chuàng)新互聯(lián)

前言

成都創(chuàng)新互聯(lián)主營(yíng)宣城網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app開(kāi)發(fā),宣城h5小程序制作搭建,宣城網(wǎng)站營(yíng)銷(xiāo)推廣歡迎宣城等地區(qū)企業(yè)咨詢

本文作者趙杭天。他參加了“2022 RTE(Real-time Engagement,實(shí)時(shí)互動(dòng)) 編程挑戰(zhàn)賽”——“賽道二 場(chǎng)景化白板插件應(yīng)用開(kāi)發(fā)” , 并憑借作品“成語(yǔ)解謎”獲獎(jiǎng)。“成語(yǔ)解謎”是一個(gè)基于互動(dòng)白板 SDK 的互動(dòng)小游戲應(yīng)用。通過(guò)前端編碼、調(diào)用白板 API 能力、定制化后端邏輯等,實(shí)現(xiàn)了一個(gè)老少咸宜、寓教于樂(lè)的成語(yǔ)解謎游戲。其中的流程、步驟與相關(guān)的技術(shù)棧在白板互動(dòng)應(yīng)用開(kāi)發(fā)上具有一定的通用性。本文將分享該項(xiàng)目的開(kāi)發(fā)過(guò)程,包括一些關(guān)鍵功能的實(shí)現(xiàn),希望與各位同學(xué)一起交流,共同進(jìn)步。大家可以訪問(wèn) game.willtian.cn/idiom2/,在線體驗(yàn)該作品。

01 選題

為什么要做這樣一款小游戲?有幾個(gè)原因。

零幾年剛上小學(xué)的時(shí)候,第一次接觸到電腦和教育軟件,里面有一些小游戲,真的會(huì)被引導(dǎo)去學(xué)習(xí)到一些東西,比如一些名詞概念、科學(xué)常識(shí),對(duì)小孩子挺有幫助。

“白板”兩個(gè)字,給我的第一感覺(jué)是回到了校園。在學(xué)校里都能遇到很好的同學(xué)和老師,有很多美好的回憶。小時(shí)候喜歡讀成語(yǔ)字典,就像看故事書(shū),然后在教室里也會(huì)玩一些類(lèi)似成語(yǔ)解謎這樣的字謎游戲。

20 年疫情在家會(huì)玩一些益智休閑游戲,能玩到自己做的游戲,感覺(jué)很開(kāi)心。另外,這類(lèi)游戲很適合碎片化的時(shí)間,并且能讓用戶學(xué)習(xí)到一些東西。尤其適合小朋友和喜歡休閑游戲的大朋友;對(duì)于長(zhǎng)輩,操作上比較友好,內(nèi)容也容易引起共鳴。從市場(chǎng)和社會(huì)上看,都是有價(jià)值的。

02 什么是互動(dòng)白板 SDK

互動(dòng)白板的正式名稱叫聲網(wǎng) Flat,官方的解釋是:“個(gè)人老師可直接使用的在線授課軟件,開(kāi)箱即用,前后端完全開(kāi)源,快速搭建簡(jiǎn)約美觀的在線教室”。它運(yùn)行起來(lái)初始界面長(zhǎng)這樣子:

圖片

互動(dòng)白板初始界面

左側(cè)工具欄圖標(biāo)告訴我們,這是一個(gè)可以在上面寫(xiě)寫(xiě)畫(huà)畫(huà)的東西。它具有這些特點(diǎn):

1.互動(dòng)性,每個(gè)房間對(duì)應(yīng)一個(gè)互動(dòng)白板,默認(rèn)情況下,房間內(nèi)所有人都可以操作白板,并且交互效果所有人可見(jiàn)的;

2.擴(kuò)展性,除基本的書(shū)寫(xiě)、涂鴉功能外,互動(dòng)白板支持自定義應(yīng)用(點(diǎn)擊工具欄最下面的“田”字型圖標(biāo)查看所有應(yīng)用);

個(gè)人認(rèn)為支持各種 APPs 是 Flat 互動(dòng)白板最強(qiáng)大的功能,通過(guò) Flat 提供的 SDK 能力,我們可以實(shí)現(xiàn)許多復(fù)雜的功能的白板應(yīng)用。

圖片

每個(gè)房間對(duì)應(yīng)一個(gè)白板

互動(dòng)白板的內(nèi)容,包括文字、涂鴉以及 App,可由 SDK 中的 Window Manager 對(duì)象來(lái)控制。可以通過(guò)官方提供的 demo 來(lái)快速熟悉一個(gè)App開(kāi)發(fā)流程。利用 Window Manager 的 API 接口,我們可以完成應(yīng)用實(shí)例通信等操作,具體例子請(qǐng)見(jiàn)后文。

03 架構(gòu)規(guī)劃

在展開(kāi)具體例子前,先介紹“成語(yǔ)解謎“項(xiàng)目的整體框架。如下圖,我們將前后端分離的方式,前端專注頁(yè)面繪制與互動(dòng),后端專注題目生成與結(jié)果判斷。用戶訪問(wèn)前端頁(yè)面無(wú)需下載全量詞庫(kù),大幅提高訪問(wèn)速度。前端利用 Window Manager 的 context API 接口,在聲網(wǎng)服務(wù)器上進(jìn)行 App 實(shí)例的同步與廣播。

圖片

前端 App 實(shí)例與聲網(wǎng)服務(wù)、游戲后端的通信

04 界面設(shè)計(jì)

我們采用“設(shè)計(jì)驅(qū)動(dòng)”的開(kāi)發(fā)模式,首先畫(huà)出設(shè)計(jì)圖,然后一步一步的把腦海里的畫(huà)面通過(guò)代碼變成現(xiàn)實(shí) :

圖片

設(shè)計(jì)草圖

游戲主界面設(shè)計(jì)圖如上,交互設(shè)計(jì)如下:

1.謎面隨機(jī)出現(xiàn)若干個(gè)成語(yǔ),這些成語(yǔ)由公共字進(jìn)行關(guān)聯(lián),作為生成的約束條件;

2.成語(yǔ)間關(guān)聯(lián)的公共字被挖走并隨機(jī)排列,作為候選字;

3.用戶通過(guò)“觸摸->拖拽->放置” 交互操作候選字的完成對(duì)謎面的補(bǔ)全;

4.“提交”得到對(duì)用戶謎面的判斷結(jié)果,分別對(duì)應(yīng)通關(guān)與未通過(guò)的場(chǎng)景;

5.“重置”將謎面和候選字恢復(fù)到游戲初始狀態(tài);

6.“答案”通過(guò)彈窗展示謎面包含成語(yǔ)的信息,包括字型、字音、釋義、出處以及用例;

(對(duì)于比較復(fù)雜的場(chǎng)景,建議把場(chǎng)景直接切換的邏輯都畫(huà)出來(lái),形成一個(gè)比較完成的需求文檔)

抓住主要矛盾,優(yōu)先完成核心功能的開(kāi)發(fā),實(shí)現(xiàn)產(chǎn)品原型后,再繼續(xù)打磨,解決次要矛盾。

05 前端開(kāi)發(fā)

完成游戲基本界面設(shè)計(jì)后,我們開(kāi)始選擇前端框架并完成界面開(kāi)發(fā)。

適合游戲開(kāi)發(fā)的前端框架很多,Three.js、Phaser、Cocos2d-js等,針對(duì)具體需求選擇。個(gè)人感覺(jué) Three.js 比較底層,用來(lái)寫(xiě)游戲代碼量可能比較大。Cocos2d-js 封裝程度較高,需要熟悉Cocos的工具鏈,對(duì)于非專業(yè)做游戲的同學(xué)而言,上手難度不低而且技術(shù)可遷移性不高。

這里選擇的是 PixiJS,PixiJS 是一個(gè)基于 2D WebGL 的渲染引擎,兼容HTML5 Canvas。它有一系列合理、整潔的 APIs,支持 Sprite,將對(duì)象抽象為各種層級(jí)的 Container。類(lèi)似 React/Vue 數(shù)據(jù)驅(qū)動(dòng)的設(shè)計(jì),在 PixiJS 中,通過(guò)修改 Container 的參數(shù),即可產(chǎn)生用戶界面的變化。Pixi 的 API 實(shí)際上是 Flash 率先使用的,經(jīng)過(guò)反復(fù)改進(jìn),有 Flash 經(jīng)驗(yàn)的同學(xué)極易上手。

入口

以“成語(yǔ)解謎”為例,我們來(lái)介紹編碼的一些細(xì)節(jié)。首先我們找到自己代碼的掛載點(diǎn),根據(jù)文檔給出的 demo 或者本文提供的例子,找到這個(gè)入口文件:

圖片

自定義應(yīng)用的入口(src/index.js)

注意到const box = context.getBox();這一行,box 對(duì)應(yīng)這個(gè)應(yīng)用打開(kāi)的窗口。我們通過(guò)box.mountContent向窗口掛載了包含我們的 App 實(shí)例的 div 容器$content

App 類(lèi)

接下來(lái),我們定義 App 類(lèi)。關(guān)鍵代碼如下。

圖片

App 類(lèi)(src/app.js)App 類(lèi)中持有一個(gè)PIXI.Application實(shí)例,此外 App 類(lèi)還持有一些相對(duì) App 維度上的變量與方法,例如:從setup(見(jiàn) src/index.js)里透?jìng)鞯倪^(guò)來(lái)的context(用于調(diào)用 Window Manager 的 API)、App 實(shí)例的 id(用于前端區(qū)分 App 實(shí)例)、layers(圖層)、resizeObserver(用于監(jiān)聽(tīng)界面變化并自適應(yīng)布局)getRandomString(生成每局游戲的 token,用于后端交互)、storage(用于在聲網(wǎng)服務(wù)器上存取App的狀態(tài))等。

Scene類(lèi)

我們?yōu)槊總€(gè)場(chǎng)景寫(xiě)一個(gè) Scene 類(lèi),這里只有一個(gè)場(chǎng)景。App 類(lèi)實(shí)例化了 Scene 類(lèi),并使用addChildscene實(shí)例加入渲染。接下來(lái)我們?yōu)橹鹘缑鎸?xiě)一個(gè) Scene。關(guān)鍵代碼如下:

圖片

Scene 類(lèi)(src/scene.js)

在 Scene 的構(gòu)造函數(shù)里實(shí)例化了“提交”、“重置”和“答案”三個(gè)按鍵,并定義了對(duì)應(yīng)事件。我們?cè)?Scene 里實(shí)例化了類(lèi) Idiom,一個(gè) Idiom 實(shí)例對(duì)應(yīng)一套字謎與候選字,Idiom 又有子對(duì)象 Piece,Piece 對(duì)應(yīng)具體的每一個(gè)字塊。由于 Scene 的按鍵事件函數(shù)的需要,我們把Piece 狀態(tài)的保存/讀取方法寫(xiě)在了 Scene 類(lèi)里。

Idiom 類(lèi) & Piece 類(lèi)

我們?cè)?Idiom 類(lèi)里定義了謎面與候選字的(Piece)字塊生成方法、重置方法、拖拽生效方法。在 Piece 類(lèi)中實(shí)現(xiàn)拖拽時(shí)的外觀行為。

圖片

Idiom 類(lèi)(src/idiom.js)

圖片

Piece 類(lèi)(src/piece.js)

整體效果圖片

主界面運(yùn)行效果

06 后端開(kāi)發(fā) 實(shí)例關(guān)聯(lián)與隔離

由于詞庫(kù)比較大,用戶每次加載完整詞庫(kù)會(huì)消耗較多的帶寬和時(shí)間,對(duì)用戶體驗(yàn)影響較大。我們通過(guò)搭建后端將謎面的獲取、提交結(jié)果的驗(yàn)證、答案的獲取,進(jìn)行服務(wù)化,提升用戶體驗(yàn)。

如上文“架構(gòu)規(guī)劃”所述,我們和每個(gè) App 實(shí)例均持有一個(gè) token,用于與后端通信時(shí),對(duì)應(yīng)上后端的游戲?qū)嵗龑?duì)象。UserGames 的 key 即為 token,在接受到瀏覽器發(fā)來(lái)的請(qǐng)求后,后端會(huì)在 UserGames 中查找相應(yīng)的游戲?qū)嵗?BoardGame,并得到當(dāng)前的游戲狀態(tài),包括謎面 table、答案 answers、答案解析 answerDetail 等。

圖片

使用 UserGames 的 key(token) 來(lái)隔離游戲?qū)嵗⑴c前端 App 實(shí)例關(guān)聯(lián)

謎面生成

謎面是怎么生成的呢,基本的算法思路是:

1.預(yù)處理成語(yǔ)庫(kù),建立所有成語(yǔ)的字索引NthOfChar *[]map[rune][][]rune,保存第 n 個(gè)字為 m 的信息;

2.使用 DFS 遞歸搜索謎面。在當(dāng)前成語(yǔ)找一個(gè)字 k 作為下一個(gè)生成開(kāi)始的節(jié)點(diǎn),根據(jù)約束條件,選定新成語(yǔ)以及新成語(yǔ)擺放位置:

a. k 必須出現(xiàn)在新成語(yǔ)中;

b. 新成語(yǔ)放置后須保證當(dāng)前謎面不被破壞;

搜索的過(guò)程中使用索引NthOfChar實(shí)現(xiàn)剪枝;

多解兼容

我們通過(guò)生成算法形成的謎面同時(shí)會(huì)產(chǎn)生 1 個(gè)唯一的答案。但實(shí)際上可能答案并不唯一,尤其是在成語(yǔ)較多時(shí),交換某幾個(gè)字,亦可生成合理的答案。針對(duì)這種情況,我需要逐個(gè)校驗(yàn)用戶提交的成語(yǔ)。若成語(yǔ)庫(kù)里總共有 N 個(gè)成語(yǔ),對(duì)成語(yǔ)庫(kù)的成語(yǔ)生成字典樹(shù) Trie,可以將查找時(shí)間復(fù)雜度從 O(N) 下降到 O(1),最多 4 次搜索。

全局單例

負(fù)責(zé)游戲?qū)嵗傻慕Y(jié)構(gòu)體 GlobalBoard 儲(chǔ)存了全量成語(yǔ)以及中間數(shù)據(jù)信息,作為全局單例,減少內(nèi)存拷貝;對(duì)于每個(gè)問(wèn)題(謎面)獲取的請(qǐng)求,直接返回 GlobalBoard 生成結(jié)果的拷貝。

圖片

使用全局單例與狀態(tài)拷貝的方式優(yōu)化內(nèi)存使用

07 App 實(shí)例通信 實(shí)例狀態(tài)的同步

到目前為止,我們基本實(shí)現(xiàn)單用戶的游戲。但是當(dāng)我們打開(kāi)兩個(gè)瀏覽器 tab 模擬多用戶操作時(shí)會(huì)發(fā)現(xiàn),App 的交互僅對(duì)當(dāng)前用戶生效,其他用戶是無(wú)感知的。表現(xiàn)為,A 用戶打開(kāi) App,拖拽到 App 窗口合適的位置,開(kāi)始游戲,將候選詞與空字塊交換,然后提交;同時(shí),B 用戶在同一房間,卻只看到了 A 打開(kāi) App,拖拽 App,看到的 App 內(nèi)容與 A 的 App 展示內(nèi)容并不同步,也感知不到 A 對(duì) App 做的操作(能看到 A 鼠標(biāo)光標(biāo)運(yùn)動(dòng),這是 Flat 兜底的同步邏輯)。

針對(duì)當(dāng)前問(wèn)題,我們可以自然想到必須有某種機(jī)制,使用戶在本地對(duì) App 實(shí)例操作后,同步狀態(tài)到某個(gè)所有用戶可訪問(wèn)的遠(yuǎn)端服務(wù)里,然后通知所有用戶將遠(yuǎn)端服務(wù)儲(chǔ)存的狀態(tài)同步到本地 App 實(shí)例中,重新渲染 App 畫(huà)面,這樣才可以實(shí)現(xiàn)多用戶的互動(dòng)。

談到這里,大家可能會(huì)想到,那我們是否可以在自己寫(xiě)的后端服務(wù)中加入同步功能呢?讓我們構(gòu)思一下做這樣的同步功能需要做哪些事:

1.設(shè)計(jì)一套通信機(jī)制,本地實(shí)例能夠主動(dòng)感知遠(yuǎn)端狀態(tài)的更新;

2.處理好超時(shí)、重連、弱網(wǎng)等問(wèn)題;

3.延遲足夠低,能接受業(yè)務(wù)波動(dòng)的負(fù)載;

4.服務(wù)經(jīng)過(guò)充分的測(cè)試,足夠穩(wěn)定;

仔細(xì)思考會(huì)發(fā)現(xiàn),穩(wěn)定可靠的實(shí)時(shí)通信其實(shí)是一個(gè)比較大的課題,并不應(yīng)該成為實(shí)現(xiàn)業(yè)務(wù)、產(chǎn)生業(yè)務(wù)價(jià)值的一個(gè)主要工作,換言之,自己造輪子的投入產(chǎn)出并不高。聲網(wǎng)在實(shí)時(shí)網(wǎng)絡(luò)通信領(lǐng)域耕耘多年,基于其技術(shù)積累,在 Flat 項(xiàng)目中提供一系列非常有用的通信 APIs,這些 APIs 設(shè)計(jì)與 React 很像,比較容易上手。下面我們通過(guò)這些 APIs 進(jìn)行同步與廣播,解決互動(dòng)性的問(wèn)題。

讓我們回到前端代碼里,在 app.js 的 App 類(lèi)做一些修改:

圖片

初始化實(shí)例的storage

我們給每個(gè) App 實(shí)例持有一份storage對(duì)象,storage對(duì)象來(lái)自白板應(yīng)用創(chuàng)建時(shí)得到的 context。這里的storage.ensureState用以確保storage.state包含某些初始值。context.storage實(shí)際上關(guān)聯(lián)了遠(yuǎn)端服務(wù)的一個(gè)存儲(chǔ)實(shí)例,它實(shí)時(shí)監(jiān)聽(tīng)到本地 storage 的變化,當(dāng)變化發(fā)生時(shí),將自動(dòng)同步最新的 storage 到服務(wù)端。即使是不同的用戶,同一房間相同的應(yīng)用實(shí)例,實(shí)際上會(huì)對(duì)應(yīng)到同一個(gè)遠(yuǎn)端 storage,畫(huà)一張圖直觀一些:

圖片

storage關(guān)聯(lián)關(guān)系圖

弄明白 storage 的同步特性,我們要做的就是在游戲狀態(tài)發(fā)生變化的時(shí)候更新 context.storage,以及增加監(jiān)聽(tīng) context.storage 變化的回調(diào)事件,將遠(yuǎn)端 context.storage 同步到游戲(應(yīng)用實(shí)例)中。

我們將狀態(tài)的 push/pull 方法做封裝,使代碼更利于維護(hù)。這里的storage.setState和 React 的 setState 類(lèi)似,更新storage.state并同步到所有客戶端。

圖片

圖片

游戲狀態(tài) ->遠(yuǎn)端storage

增加監(jiān)聽(tīng)事件,addStateChangedListener在有人調(diào)用storage.setState()后觸發(fā) (包含當(dāng)前storage) ,在這里我們編寫(xiě)將遠(yuǎn)端storage同步到游戲狀態(tài)的邏輯。

圖片

遠(yuǎn)端 storage ->游戲狀態(tài)

分布式鎖

設(shè)想這么一個(gè)場(chǎng)景,我們的用戶需要共同操作同一個(gè) App 實(shí)例,比如共同完成一場(chǎng)解謎游戲,用戶 A、B 幾乎同時(shí)點(diǎn)擊了“提交”,后端接到提交請(qǐng)求,判斷答案正確,然后為游戲?qū)嵗职l(fā)新的題目,此時(shí),若后端在為 A 分發(fā)題目的過(guò)程中 B 的請(qǐng)求到達(dá),且也給 B 分發(fā)新的題目,會(huì)導(dǎo)致 A、B 前端收到不一致的新題目。此外,還有一種場(chǎng)景,用戶 C 因?yàn)槿蹙W(wǎng)或其他原因,提交后未馬上收到反饋,重復(fù)頻繁地點(diǎn)擊提交,將導(dǎo)致發(fā)起重復(fù)請(qǐng)求,用戶較多且請(qǐng)求時(shí)間集中時(shí),容易導(dǎo)致負(fù)載波動(dòng),影響服務(wù)質(zhì)量。

因此,我們有必要為“提交”增加一個(gè)分布式的鎖,使在某個(gè) App 實(shí)例里,所有時(shí)間里,只能由一個(gè)用戶提交。

圖片

通過(guò) context.storage 實(shí)現(xiàn)分布式鎖

實(shí)例廣播

當(dāng)對(duì)于某個(gè) App 實(shí)例,某個(gè)用戶提交通過(guò)得到新的游戲狀態(tài)(新的謎面與候選詞等)后,需要將狀態(tài)同步給其他用戶。實(shí)際上我們可以將獲取新游戲與狀態(tài)寫(xiě)入本地游戲這兩步分離,在進(jìn)行廣播時(shí)自己也會(huì)接收到,所有包括自己在內(nèi)的用戶監(jiān)聽(tīng)到廣播立即寫(xiě)入本地游戲。如圖所示:

圖片

先獲取新?tīng)顟B(tài)再通過(guò)廣播進(jìn)行狀態(tài)同步的流程

我們可以利用廣播與監(jiān)聽(tīng)API context.dispatchMagixEvent(event, payload)context.addMagixEventListener(event, listener)上述功能:

圖片

圖片

在游戲狀態(tài)發(fā)生變化(提交成功和重置)時(shí)廣播

圖片

監(jiān)聽(tīng)廣播發(fā)生,并根據(jù)具體事件做不同操作

至此,我們的跨越前后端的實(shí)例通信部分也完成了,實(shí)現(xiàn)了用戶對(duì) App 實(shí)例操作時(shí)交互的同步,并處理了如同時(shí)、重復(fù)提交這類(lèi)的并發(fā)問(wèn)題。此類(lèi)問(wèn)題在其他互動(dòng)應(yīng)用的開(kāi)發(fā)中也普遍存在,這里提供了一些參考。

08 小結(jié)

聲網(wǎng) Flat 開(kāi)源項(xiàng)目提供了白板 SDK,支持開(kāi)發(fā)自定義 App,為在線教育和白板應(yīng)用提供了巨大的想象空間。本次分享從一個(gè)初次接觸 Flat 開(kāi)發(fā)者的視角,介紹了互動(dòng)白板的特點(diǎn),并從基于實(shí)際例子——完成一款互動(dòng)小游戲,分享了小游戲前端框架的選擇與使用、整體架構(gòu)設(shè)計(jì)思路、后端開(kāi)發(fā)流程等。同時(shí)介紹一些實(shí)用的 window-manager API,并在實(shí)戰(zhàn)中如何使用這些 APIs 來(lái)快速解決一些原本比較復(fù)雜的問(wèn)題。希望能對(duì)大家開(kāi)發(fā)Flat白板自定義應(yīng)用、在線互動(dòng)小游戲中提供一些參考和幫助。由于時(shí)間倉(cāng)促,仍存在許多有待完善和優(yōu)化的點(diǎn),請(qǐng)大家不吝指出。拋磚引玉,互動(dòng)教育、教育游戲等在國(guó)內(nèi)外仍有較大的市場(chǎng)前景,希望與大家有更多的交流與合作,謝謝大家。

參考
  • https://github.com/netless-io/window-manager/blob/master/docs/develop-app.md

  • https://github.com/netless-io/window-manager/blob/master/docs/app-context.md

成語(yǔ)解謎:

  • https://github.com/Zhao-hangtian/happy-star

大賽作品倉(cāng)庫(kù):

https://github.com/AgoraIO-Community/RTE-2022-Innovation-Challenge

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

分享題目:基于聲網(wǎng)Flat實(shí)現(xiàn)“成語(yǔ)解謎”的Web小游戲-創(chuàng)新互聯(lián)
分享鏈接:http://chinadenli.net/article0/cddioo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)面包屑導(dǎo)航網(wǎng)站收錄關(guān)鍵詞優(yōu)化外貿(mào)網(wǎng)站建設(shè)ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

綿陽(yáng)服務(wù)器托管