成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

React庫(kù)+GraphQL服務(wù)器+Relay架構(gòu)聯(lián)合作戰(zhàn)(上)

譯文
開(kāi)發(fā) 后端
本系列文章較全面地分析了時(shí)下流行的React庫(kù)、GraphQL服務(wù)器以及Relay架構(gòu)模式各自的功能特征,并通過(guò)一個(gè)具體的實(shí)例向你展示它們是如何相互配合來(lái)完成一款Web應(yīng)用的開(kāi)發(fā)的。

 【摘要】本系列文章較全面地分析了時(shí)下流行的React庫(kù)、GraphQL服務(wù)器以及Relay架構(gòu)模式各自的功能特征,并通過(guò)一個(gè)具體的實(shí)例向你展示它們是如何相互配合來(lái)完成一款Web應(yīng)用的開(kāi)發(fā)的。本篇屬于本系列的上篇,側(cè)重于React庫(kù)、GraphQL服務(wù)器和Relay架構(gòu)各自功能及其關(guān)系解析。

[[170372]]

概述

不同于如AngularJS和Ember這樣的框架,React是一個(gè)客戶(hù)端庫(kù),其中提供了一組有限的函數(shù),而且該庫(kù)幾乎獨(dú)立于構(gòu)建應(yīng)用程序其他功能時(shí)所可能需要的其他庫(kù)。從根本上說(shuō),React提供了客戶(hù)端UI組件功能,其中提供了一種機(jī)制來(lái)創(chuàng)建組件、管理組件中的數(shù)據(jù),渲染組件,以及復(fù)合小組件來(lái)構(gòu)建更大的組件。React可以用于多種情景下,無(wú)論數(shù)據(jù)來(lái)自何處、 如何檢索數(shù)據(jù)或如何把數(shù)據(jù)作為一個(gè)更大的應(yīng)用程序的一部分進(jìn)行管理的。為了有效地對(duì)付這些問(wèn)題,需要利用其他的庫(kù)和模式。一個(gè)用于React應(yīng)用程序的常見(jiàn)模式是Flux。

人們開(kāi)發(fā)Flux的目的是把它作為MVC(模型-視圖-控制器)模式的一種替代方法,來(lái)管理響應(yīng)動(dòng)作的數(shù)據(jù)流。與MVC的雙向數(shù)據(jù)流動(dòng)不同,F(xiàn)lux依賴(lài)于系統(tǒng)中的各個(gè)部件之間的單向數(shù)據(jù)流。Flux是Facebook創(chuàng)建的,因?yàn)樗麄兊拈_(kāi)發(fā)人員發(fā)現(xiàn)很難了解采用MVC模式開(kāi)發(fā)的大型應(yīng)用程序中的數(shù)據(jù)運(yùn)動(dòng)規(guī)律。

不同于MVC模式所采用的多環(huán)路數(shù)據(jù)流,F(xiàn)lux使用的是單環(huán)路數(shù)據(jù)流方案。數(shù)據(jù)僅沿著一條線(xiàn)路流動(dòng),這條線(xiàn)路是:動(dòng)作(Action)->調(diào)度器(Dispatcher)->存儲(chǔ)(Store)(或多個(gè)存儲(chǔ))->組件(即視圖)->動(dòng)作。

其中,動(dòng)作(Action)表示某種進(jìn)入系統(tǒng)的事件。這可能是用戶(hù)生成的,如請(qǐng)求刷新數(shù)據(jù)的按鈕單擊事件,或者也可能是通過(guò)一個(gè)Web套接字接收消息事件。然后,這個(gè)動(dòng)作被傳遞給調(diào)度器將它發(fā)送到所有的存儲(chǔ)。調(diào)度器其實(shí)只不過(guò)是一個(gè)轉(zhuǎn)發(fā)機(jī)制。它不懂動(dòng)作是什么,動(dòng)作所傳遞的數(shù)據(jù)的含義,而也不懂得與該動(dòng)作相關(guān)的每個(gè)存儲(chǔ)的功能。它只是把動(dòng)作調(diào)度給所有的存儲(chǔ),然后每個(gè)存儲(chǔ)決定是否應(yīng)該處理這一動(dòng)作。存儲(chǔ)負(fù)責(zé)維護(hù)數(shù)據(jù)的本地副本,強(qiáng)制實(shí)施業(yè)務(wù)規(guī)則并通知新數(shù)據(jù)的組件,以便能刷新它們。你可以認(rèn)為存儲(chǔ)是維護(hù)應(yīng)用程序狀態(tài)的,而整個(gè)Flux流程本質(zhì)上就是一個(gè)狀態(tài)機(jī)。因此,React組件利用了狀態(tài)機(jī)模式。在某種意義上,F(xiàn)lux利用與此相同的狀態(tài)機(jī)模式來(lái)架構(gòu)整個(gè)應(yīng)用程序。

雖然Flux是解決數(shù)據(jù)流問(wèn)題的一種模式,但它本身并沒(méi)有提供實(shí)現(xiàn)這種模式的技術(shù)。若要使用Flux模式,開(kāi)發(fā)人員不得不創(chuàng)建系統(tǒng)中所有的組件,除了Facebook提供的調(diào)度器之外。創(chuàng)建一個(gè)Flux系統(tǒng)是相對(duì)比較容易的,但它需要大量的樣板代碼。在這方面,它面臨與Backbone.js同樣的問(wèn)題。啟動(dòng)和運(yùn)行系統(tǒng)是很容易的,但最終需要大量的編碼。

Flux進(jìn)化過(guò)程

當(dāng)開(kāi)發(fā)人員使用Flux時(shí),他們開(kāi)始想辦法來(lái)把樣板代碼重構(gòu)到可重用的庫(kù)中。此外,他們還能夠確定出Flux中的子模式,這使得對(duì)于應(yīng)用程序中數(shù)據(jù)流的分析判斷更為容易,而且還在而不犧牲Flux一般優(yōu)點(diǎn)的情況下減少應(yīng)用程序的復(fù)雜性。這些子模式包括:把應(yīng)用程序中的多存儲(chǔ)減少到一個(gè)存儲(chǔ);把調(diào)度器與存儲(chǔ)結(jié)合到相同的組件(當(dāng)只有一個(gè)存儲(chǔ)時(shí)這是很重要的)中;而且,還能夠把諸多組件封裝到一個(gè)容器中,此容器中可以在黑箱中創(chuàng)建動(dòng)作、調(diào)度和進(jìn)行存儲(chǔ)管理。如今,許多Flux的衍生產(chǎn)品不再僅僅局限于純粹的Flux功能,而且還能夠在保留其根本要素的同時(shí)避免Flux通常的缺點(diǎn),即大量的樣板代碼的問(wèn)題。

目前,雖然有很多Flux的衍生產(chǎn)品,但是Redux是更受歡迎的模式之一。Redux純粹基于狀態(tài)機(jī)概念和不可變數(shù)據(jù)的思想而構(gòu)建。在該模式中,動(dòng)作都由單一的“調(diào)度器-存儲(chǔ)”來(lái)處理;這些“調(diào)度器-存儲(chǔ)”對(duì)象使用reducer函數(shù)(它們本身是可以組合的)實(shí)現(xiàn)把一種狀態(tài)轉(zhuǎn)換到另一種狀態(tài)。這就在極大地簡(jiǎn)化Flux模式的同時(shí)引進(jìn)很多函數(shù)編程特征;一旦你徹底掌握這一技術(shù),React應(yīng)用程序編碼將容易許多。

Relay是來(lái)自于Facebook團(tuán)隊(duì)的另一個(gè)Flux的衍生產(chǎn)品,此模式日漸普及。關(guān)于Facebook如何使用Relay以及其與Flux關(guān)系的處理方案的更多信息,請(qǐng)參考網(wǎng)址https://facebook.github.io/react/blog/2015/02/20/introducing-relay-and-graphql.html

Relay框架功能分析

雖然Redux簡(jiǎn)化了應(yīng)用程序的管理,但是在實(shí)際數(shù)據(jù)定位方面卻不可知。它可以使用任何數(shù)據(jù)存儲(chǔ)系統(tǒng),但是再一次導(dǎo)致更多的樣板代碼(雖然少于Flux)問(wèn)題。于是,出現(xiàn)了Relay (這是Facebook創(chuàng)建的另一個(gè)產(chǎn)品,其應(yīng)用了其他大量的JavaScript開(kāi)源產(chǎn)品,例如React,Relay,Immutable.js,GraphQL,Jest,F(xiàn)low等),它的宗旨在于通過(guò)重構(gòu)去除數(shù)據(jù)訪問(wèn)相關(guān)的樣板代碼部分,同時(shí)還引進(jìn)另一種新的數(shù)據(jù)服務(wù)——GraphQL。GraphQL不同于傳統(tǒng)REST服務(wù)的地方在于,它把數(shù)據(jù)視為一個(gè)圖形,并力求以分層方式來(lái)描述該圖形,從而使數(shù)據(jù)消費(fèi)者自己指定他們需要的數(shù)據(jù),而不是傳統(tǒng)的REST服務(wù)中那樣提供一組固定的數(shù)據(jù)集服務(wù)而不考慮消費(fèi)者需求。

那么,Relay到底是做什么的呢?Relay是一個(gè)框架,它負(fù)責(zé)把React組件連接到GraphQL服務(wù)器,此連接是通過(guò)一個(gè)實(shí)現(xiàn)了動(dòng)作、調(diào)度器和存儲(chǔ)的容器實(shí)現(xiàn)的。開(kāi)發(fā)人員不需要對(duì)動(dòng)作、調(diào)度器和存儲(chǔ)進(jìn)行編程,而可以觸發(fā)這些動(dòng)作并通過(guò)Relay API來(lái)訪問(wèn)相應(yīng)的結(jié)果。若要配置容器,開(kāi)發(fā)人員必須提供GraphQL查詢(xún)和突變片段(mutation fragments)向容器描述數(shù)據(jù)的圖結(jié)構(gòu);此外,Relay還會(huì)負(fù)責(zé)照顧數(shù)據(jù)管理的所有細(xì)節(jié)。

Relay的確是一個(gè)框架(如Angular),而不是一個(gè)庫(kù)。它的實(shí)現(xiàn)可以說(shuō)是透明的——它需要通過(guò)React實(shí)現(xiàn)UI組件而且由GraphQL提供數(shù)據(jù)服務(wù)。一旦GraphQL服務(wù)器和React組件配置到位,Relay將接管并執(zhí)行所有需要的操作。因此,使用Relay的關(guān)鍵是掌握配置過(guò)程。

此外,與框架Angular(它僅對(duì)客戶(hù)端有專(zhuān)門(mén)需求)不同,Relay還要求GraphQL服務(wù)器接口來(lái)為Relay容器提供數(shù)據(jù)查詢(xún)和變異操作。但是,只要通過(guò)特定的GraphQL接口提供數(shù)據(jù),Relay并不在意如何存儲(chǔ)數(shù)據(jù)。

因此,Relay需要后端和前端兩個(gè)開(kāi)發(fā)團(tuán)隊(duì)都要了解它的工作原理,并要求他們弄清程序的的每個(gè)部件(無(wú)論前端還是后端)是如何編碼和配置的。

Relay與React的配合

本小節(jié)中,讓我們從React的角度來(lái)研究一下Relay。程序員們可以使用多種語(yǔ)言對(duì)GraphQL服務(wù)器進(jìn)行編碼與配置,并部署到多種平臺(tái)上。對(duì)于Node.js環(huán)境下的GraphQL實(shí)現(xiàn)來(lái)說(shuō),有一個(gè)稱(chēng)為graphql-relay(https://www.npmjs.com/package/graphql-relay)的包可以用于簡(jiǎn)化GraphQL服務(wù)器的編碼和配置要求。在React方面,則存在一個(gè)名為relay-react(https://www.npmjs.com/package/react-relay)的包可用于配置Relay容器和路由,還能夠激發(fā)動(dòng)作來(lái)實(shí)現(xiàn)數(shù)據(jù)變異操作等。

Relay開(kāi)發(fā)入門(mén)

入門(mén)Relay是有些難度的。因?yàn)樵摷夹g(shù)是如此之新而且有很多的競(jìng)爭(zhēng)對(duì)手,所以,有關(guān)如何使用Relay的參考資源目前還相當(dāng)有限。而提供資源的地方,一般提供的例子也是很有限的;為此,開(kāi)發(fā)人員最終被迫去閱讀博客文章、翻閱GitHub問(wèn)題和正式的產(chǎn)品說(shuō)明書(shū)才能創(chuàng)建一個(gè)簡(jiǎn)單的CRUD應(yīng)用程序。此外,還需要搭建一個(gè)相當(dāng)復(fù)雜的開(kāi)發(fā)環(huán)境以及需要有一個(gè)正確配置的GraphQL服務(wù)器。因此,這樣的任務(wù)對(duì)于JavaScript/前端開(kāi)發(fā)新手而言可能相當(dāng)艱巨。

作為準(zhǔn)備工作,請(qǐng)首先克隆一下GitHub網(wǎng)站上的存儲(chǔ)倉(cāng)庫(kù)(https://github.com/DevelopIntelligenceBoulder/react-flux-blog)到您的計(jì)算機(jī)上,并打開(kāi)相應(yīng)的文件夾blog-post-5+6。此文件夾包含一個(gè)完整的GraphQL/React/Relay應(yīng)用程序。為了便該應(yīng)用程序啟動(dòng)并運(yùn)行起來(lái),請(qǐng)打開(kāi)一個(gè)終端,導(dǎo)航到文件夾blog-post-5+6中,并運(yùn)行以下Gulp命令。

  1. $ npm i 
  2.  
  3. $ npm i -g gulp eslint eslint-config-airbnb eslint-plugin-react@^4.3.0 webpack babel-cli babel-eslint eslint-plugin-jsx-a11y@^0.6.2 
  4.  
  5. $ gulp 
  6.  
  7. $ npm run update-schema 
  8.  
  9. $ gulp 
  10.  
  11. $ gulp server 

現(xiàn)在,請(qǐng)打開(kāi)微軟的Edge瀏覽器(【譯者注】微軟專(zhuān)門(mén)為Windows 10配置的高性能瀏覽器),然后導(dǎo)航到下面的URL:http://localhost:3000

你會(huì)注意到,頁(yè)面中將顯示一個(gè)小控件列表,并使用Bootstrap 4風(fēng)格進(jìn)行修飾,看起來(lái)相當(dāng)漂亮。(【譯者注】因某種原因原文并沒(méi)有提供結(jié)果快照)

該項(xiàng)目的基本開(kāi)發(fā)構(gòu)架是典型的文件夾組織方式。其中,src文件夾中存放可編輯的源代碼文件,而最終的部署文件夾是dist(源代碼文件都要復(fù)制至此處),應(yīng)用程序正是使用此處的文件執(zhí)行的。復(fù)制過(guò)程是使用Gulp命令進(jìn)行的;具體地說(shuō),是通過(guò)組合一些簡(jiǎn)單的復(fù)制文件命令、創(chuàng)建一個(gè)處理SASS文件的任務(wù),還有一個(gè)針對(duì)JavaScript的Web打***程完成的。其中,Web打包處理機(jī)制使用Babel轉(zhuǎn)譯器把RelayQL、JSX和ES2015代碼轉(zhuǎn)換為 ES5.1兼容的可以在任何瀏覽器中執(zhí)行的JavaScript代碼。ES2015和JSX轉(zhuǎn)譯已經(jīng)不是什么新技術(shù),但對(duì)于RelayQL的轉(zhuǎn)譯卻是一個(gè)新課題。

RelayQL與Babel-Relay插件

GraphQL服務(wù)器能夠通過(guò)使用內(nèi)省(introspection)機(jī)制自動(dòng)生成結(jié)構(gòu)(【譯者注】原文中用詞是schema,這個(gè)詞在數(shù)據(jù)庫(kù)表格設(shè)計(jì)中常用;而其他許多軟件技術(shù)中也廣泛使用這個(gè)詞,而且經(jīng)常譯為“模式”或“架構(gòu)”。為了區(qū)別本文中另兩個(gè)詞pattern和architecture,在此特意譯為“結(jié)構(gòu)”)。結(jié)構(gòu)(schema)其實(shí)是一個(gè)JSON文件,其中描述的所有類(lèi)型由特定的GraphQL服務(wù)器使用。結(jié)構(gòu)中可以包含自定義和內(nèi)置類(lèi)型。Babel-Relay插件使用此結(jié)構(gòu)來(lái)校驗(yàn)使用RelayQL編碼形成的GraphQL片段(fragments)。這些片段是使用ES2015字符串模板編碼的,一旦它們通過(guò)根據(jù)結(jié)構(gòu)定義的校驗(yàn)就被轉(zhuǎn)換為JavaScript代碼。這種校驗(yàn)可以有效地防止 GraphQL錯(cuò)誤的發(fā)生。

配置Babel-Relay插件也是生成結(jié)構(gòu)(schema)最簡(jiǎn)單的方法是,直接使用從Relay網(wǎng)站(https://facebook.github.io/relay/docs/guides-babel-plugin.html)或Relay初學(xué)者工具包項(xiàng)目(https://github.com/relayjs/relay-starter-kit)中下載的例子。這些文件正是本文對(duì)應(yīng)的Github存儲(chǔ)庫(kù)中所使用的,并遵從Relay官網(wǎng)上推薦的開(kāi)發(fā)模式。

從Relay初學(xué)者工具包項(xiàng)目中,我們需要使用兩個(gè)文件:build/babelRelayPlugin.js和scripts/updateSchema.js。其中,UpdateSchema.js文件將用于生成結(jié)構(gòu)(schema),而babelRelayPlugin.js文件將使用結(jié)構(gòu)文件來(lái)校驗(yàn)證GraphQL片段以及轉(zhuǎn)換RelayQL代碼。

GraphQL與Relay協(xié)作

通常情況下,要使用Relay需要修改標(biāo)準(zhǔn)的GraphQL服務(wù)器實(shí)現(xiàn)方案。我們可以使用一個(gè)名為graphql-relay(https://www.npmjs.com/package/graphql-relay)的包來(lái)幫助把基于Node.js的GraphQL服務(wù)器配置為Relay兼容型的。要配置成一個(gè)Relay特定類(lèi)型的GraphQL服務(wù)器需要三個(gè)主要方面:對(duì)象標(biāo)記(Object Identification)、類(lèi)型連接(Type Connections)和突變(Mutations)。

通過(guò)使用一個(gè)全局唯一的ID值,對(duì)象標(biāo)記允許Relay從GraphQL服務(wù)器查詢(xún)實(shí)現(xiàn)了節(jié)點(diǎn)接口的任何類(lèi)型。這個(gè)全局ID是base64編碼的,其中包含類(lèi)型名稱(chēng)和一個(gè)后面跟一個(gè)冒號(hào)的本地ID值。graphql-relay庫(kù)提供了分別命名為toGlobalID和fromGlobalID的函數(shù)支持在全局 ID之間來(lái)回轉(zhuǎn)換。另外,類(lèi)型名稱(chēng)來(lái)自于在類(lèi)型配置中指定的GraphQL自定義類(lèi)型名稱(chēng)。通常情況下,本地ID值來(lái)自于數(shù)據(jù)存儲(chǔ)機(jī)制,例如關(guān)系數(shù)據(jù)庫(kù)中的標(biāo)記(Identity)。請(qǐng)參考下面的代碼:

  1. import { nodeInterface } from './../node-definitions'
  2.  
  3. export const widgetType = new GraphQLObjectType({ 
  4.  
  5. name'Widget'
  6.  
  7. description: 'A widget object'
  8.  
  9. fields: () => ({ 
  10.  
  11. id: globalIdField('Widget'), 
  12.  
  13. // more fields 
  14.  
  15. }), 
  16.  
  17. interfaces: () => [nodeInterface] 
  18.  
  19. }); 

在上面代碼中,文件node-definitions.js(及其相關(guān)文件type-registry)的作用是:為通過(guò)節(jié)點(diǎn)接口使對(duì)象可用而提供配置與類(lèi)型注冊(cè)。

第二個(gè)Relay特定的配置,即類(lèi)型連接(Type Connections),是建立父類(lèi)型及其子類(lèi)型之間的一對(duì)多關(guān)系的連接。這些連接是使用一種特殊的連接類(lèi)型結(jié)構(gòu)管理的。這些特殊的連接類(lèi)型結(jié)構(gòu)支持圖中的邊緣(graph edge)概念和游標(biāo)(cursor)的概念,用于限制結(jié)果集與生成結(jié)果頁(yè)面。可以配置連接和邊緣類(lèi)型以支持如元數(shù)據(jù)這樣的附加屬性,從而允許控制連接或邊緣特性(例如加權(quán)的邊緣等)。請(qǐng)參考下面的代碼:

  1. import { widgetType } from './types/widget-type'
  2.  
  3. import { connectionDefinitions } from 'graphql-relay'
  4.  
  5. export const { connectionType: widgetConnection, edgeType: WidgetEdge } = 
  6.  
  7. connectionDefinitions({name'Widget', nodeType: widgetType}); 

上面代碼中的ConnectionDefinitions函數(shù)用于創(chuàng)建Relay期望的結(jié)構(gòu)中的連接類(lèi)型。請(qǐng)參考下面的代碼:

  1. import { widgetConnection } from '../connections/widget-connection'
  2.  
  3. // inside of fields function of viewer type declaration 
  4.  
  5. widgets: { 
  6.  
  7. type: widgetConnection, 
  8.  
  9. description: 'A list of widgets'
  10.  
  11. args: connectionArgs, 
  12.  
  13. resolve: (_, args) => connectionFromPromisedArray(getWidgets(), args) 
  14.  

上面代碼中,WidgetConnection類(lèi)型是從widget-connection.js文件中導(dǎo)入的,用于配置查看器類(lèi)型中的控件字段。包graphql-relay中還提供了一個(gè)名為connectionArgs的對(duì)象,該對(duì)象中包含通過(guò)Relay傳遞進(jìn)來(lái)的用于處理連接的標(biāo)準(zhǔn)參數(shù)。這些參數(shù)包含的值用于游標(biāo)操作。

第三和***一個(gè)Relay特定的配置是突變(mutation)配置。graphql-relay包中提供了一個(gè)專(zhuān)門(mén)的命名為mutationWithClientMutationId的幫助方法用于簡(jiǎn)化突變配置。有四個(gè)字段是必需的:突變名稱(chēng)、輸入字段、輸出字段和獲取有效載荷的字段。在GraphQL中,所有的突變都將伴隨一個(gè)查詢(xún)來(lái)獲知任何數(shù)據(jù)可能已被更改。Relay通過(guò)智能地決定突變后需要刷新哪些數(shù)據(jù)來(lái)進(jìn)一步擴(kuò)展了這種能力。

突變的名字是當(dāng)React-Relay應(yīng)用程序訪問(wèn)GraphQL服務(wù)器時(shí)用來(lái)調(diào)用突變的名字。輸入字段對(duì)應(yīng)于GraphQL中突變的args參數(shù)。輸出字段描述了要從突變返回的類(lèi)型的字段。***一個(gè)獲取有效載荷的字段將執(zhí)行實(shí)際的數(shù)據(jù)庫(kù)操作并返回一個(gè)promise對(duì)象,該對(duì)象將推遲從GraphQL到應(yīng)用程序的響應(yīng)時(shí)間,直到該promise被解析結(jié)束為止。

小結(jié)

React和GraphQL聯(lián)手,并輔助以Relay,將為構(gòu)建Web應(yīng)用程序提供一個(gè)很有前途的框架。雖然開(kāi)發(fā)過(guò)程中需要不少的安裝及配置工作,但是一旦這些工作完畢,開(kāi)發(fā)過(guò)程將流暢地進(jìn)行下去,消除了樣板代碼,并智能地處理數(shù)據(jù)管理問(wèn)題。實(shí)踐將會(huì)證明Relay框架很可能會(huì)成為構(gòu)建下一代Web應(yīng)用程序的游戲規(guī)則改變者。在本系列下篇文章中,我們將探討使用React并配合以Relay來(lái)控制GraphQL資源的問(wèn)題。

責(zé)任編輯:趙立京 來(lái)源: 51CTO
相關(guān)推薦

2022-07-13 11:16:06

BCS2022網(wǎng)絡(luò)安全

2021-11-22 05:50:26

云計(jì)算云計(jì)算環(huán)境云應(yīng)用

2022-03-24 10:15:39

PingCAPTiDB數(shù)據(jù)庫(kù)

2020-09-30 08:46:12

智能

2024-06-11 00:00:01

用ReactGraphQLCRUD

2022-02-17 11:08:46

技嘉科技Canonical服務(wù)器

2010-05-19 10:31:07

IIS服務(wù)器

2018-05-18 09:43:37

服務(wù)器架構(gòu)大型網(wǎng)站

2014-09-22 09:52:06

2011-01-13 10:01:27

2016-08-17 22:36:33

華為華為服務(wù)器服務(wù)器

2018-03-27 17:33:31

服務(wù)器

2013-04-24 09:40:38

聯(lián)想服務(wù)器ODM

2012-11-20 09:33:35

Ubuntu服務(wù)器數(shù)據(jù)中心

2019-12-24 14:42:51

Nginx服務(wù)器架構(gòu)

2019-01-10 11:12:15

Nginx服務(wù)器架構(gòu)

2019-09-10 15:22:17

Nginx服務(wù)器架構(gòu)

2020-05-12 21:17:18

Nginx服務(wù)器架構(gòu)

2009-01-09 22:45:21

2022-04-28 11:19:13

WebRTC服務(wù)器架構(gòu)
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 国产 日韩 欧美 在线 | 请别相信他免费喜剧电影在线观看 | 99热这里都是精品 | 韩日精品视频 | 国产大片黄色 | 婷婷色国产偷v国产偷v小说 | 欧美精品久久久久久久久老牛影院 | 欧美2区| 国产精品一区二区无线 | 中文字幕一区二区三区在线观看 | 亚洲国产精品人人爽夜夜爽 | 奇米在线 | 精品视频99 | 日本免费视频在线观看 | 欧美精品在线一区二区三区 | 国产精品视频导航 | 久久精品性视频 | 麻豆视频国产在线观看 | wwww.xxxx免费 | 日韩一级免费观看 | 精品一区二区三区91 | 一级毛片视频 | 北条麻妃一区二区三区在线观看 | 午夜在线影院 | 国产欧美精品一区二区色综合朱莉 | 亚洲精品久久久久久久久久久 | 一区二区三区免费网站 | 精品人伦一区二区三区蜜桃网站 | 亚洲人成网站777色婷婷 | 黄色成人亚洲 | 久久99精品久久久久久国产越南 | 中文字幕高清av | 午夜精品在线观看 | 日韩久久久久久 | 久热m3u8 | 九色在线视频 | 成人精品国产一区二区4080 | 国产成人免费 | 欧美日韩精品免费 | 偷拍自拍网站 | 久久亚洲国产精品 |