小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

從零開發(fā)TinyWebDB原型系統(tǒng)(2)

 老巫婆圖書館 2021-07-06

在上一篇文章中,我們得出了一個(gè)重要結(jié)論,TinyWebDB本質(zhì)上就是一個(gè)典型的Web服務(wù)系統(tǒng)。那么在這篇文章中,我們就來著手實(shí)現(xiàn)這樣一個(gè)系統(tǒng)。

一、工具

市面上可用于開發(fā)Web服務(wù)系統(tǒng)的語言和工具有很多,比如Java、Python、Node.js等,但大多都面向?qū)I(yè)開發(fā)領(lǐng)域,對(duì)于非專業(yè)開發(fā)人員而言,需要跨越一定的學(xué)習(xí)門檻。為此,我們特意選擇由IBM Emerging Technology團(tuán)隊(duì)開發(fā)的Node-RED,作為我們構(gòu)建TinyWebDB原型的主要工具,實(shí)際這是一個(gè)面向物聯(lián)網(wǎng)應(yīng)用的開源可視化編程和運(yùn)行環(huán)境。

選擇Node-RED的最主要原因是,首先,它在功能、形式和概念上與App Inventor有許多共通之處,比如組件化開發(fā)模式、瀏覽器開發(fā)環(huán)境以及圖形化、拖拽式編程方式等。對(duì)具有一定App Inventor開發(fā)經(jīng)驗(yàn)的人來說,應(yīng)該很容易上手。再者,Node-RED對(duì)運(yùn)行和部署環(huán)境的適應(yīng)性較強(qiáng),除傳統(tǒng)的Windows、MacOS和Linux等桌面系統(tǒng)外,還可以部署到AWS、Azure等云平臺(tái)上。更值得關(guān)注的是,它還能在樹莓派、安卓手機(jī)這類所謂的邊緣設(shè)備上運(yùn)行,為開發(fā)和學(xué)習(xí)帶來了極大的便利。最后,憑借技術(shù)上的開源和開放,Node-RED已經(jīng)形成了豐富的組件和代碼庫生態(tài)資源,幾乎涵蓋了與物聯(lián)網(wǎng)和互聯(lián)網(wǎng)應(yīng)用相關(guān)的各個(gè)領(lǐng)域,這對(duì)于提高開發(fā)和應(yīng)用的整體效率具有十分重要的意義。

二、概念

結(jié)構(gòu)化的軟件應(yīng)用開發(fā)在某種程度上有點(diǎn)像搭積木或蓋房子,一般都先要有一些最基本的建筑塊,然后把它們按一定的方式,進(jìn)行堆砌、連接與組合,最終構(gòu)建成為一個(gè)預(yù)想的完整系統(tǒng)。在我們熟悉的App Inventor中,組件是最基本的構(gòu)筑單元,主要負(fù)責(zé)應(yīng)用與外界環(huán)境之間的連接和信息交換(當(dāng)然也可以包括一些非接口類的通用信息處理和業(yè)務(wù)功能組件),而組件功能的調(diào)用以及組件之間的協(xié)作則主要通過(預(yù)設(shè)的事件處理)過程來實(shí)現(xiàn)。從整體看,應(yīng)用是由功能構(gòu)成的主體,功能在邏輯上映射為過程,而過程的作用就是將功能分解為由各個(gè)組件承擔(dān)的具體任務(wù),并以指令的方式指派或下達(dá)給它們。

在概念上,Node-RED與App Inventor有許多對(duì)應(yīng)和相通之處。就一個(gè)具體的應(yīng)用而言,Node-RED所關(guān)注的基本要素實(shí)際只有三個(gè),即節(jié)點(diǎn)(Node)、消息(Msg)和流程(Flow)。如果排除變量、過程等自定義因素,那么節(jié)點(diǎn)其實(shí)就相當(dāng)于App Inventor中的組件,消息相當(dāng)于功能調(diào)用和屬性存取指令,而流程則相當(dāng)于(預(yù)設(shè)的事件處理)過程。為了方便理解,我們想通過一個(gè)簡(jiǎn)單的Hello World應(yīng)用,來具體說明一下二者的聯(lián)系和差別。

在App Inventor里,這是一段非常典型的事件處理邏輯,其重點(diǎn)是與功能相關(guān)的詳細(xì)指令序列及具體執(zhí)行步驟。其中,(按鈕點(diǎn)擊事件處理)過程是管控指令執(zhí)行的主體,(按鈕、標(biāo)簽和對(duì)話框等)組件對(duì)象雖然是指令的具體執(zhí)行者,但對(duì)其功能和特性的使用都要由過程來統(tǒng)一指揮和調(diào)度。換句話說,組件只是過程用來實(shí)現(xiàn)功能的道具,它的所有行為都受到過程的直接控制。反過來,過程對(duì)組件功能也具有相當(dāng)程度的依賴性和綁定性,個(gè)別組件的微小變化和改動(dòng)都有可能引起整個(gè)過程的調(diào)整。

現(xiàn)在,讓我們來轉(zhuǎn)換一下視角,把整個(gè)功能實(shí)現(xiàn)的重心由指令轉(zhuǎn)向指令的執(zhí)行者。也就是說,把原來處于從屬地位的組件提升為具有自主執(zhí)行能力的獨(dú)立個(gè)體對(duì)象,而原來承載功能邏輯的主體過程則降格為與組件對(duì)等的個(gè)體功能模塊。于是,整個(gè)功能實(shí)現(xiàn)的方式就由原來自上而下的分層控制模式轉(zhuǎn)換為自底向上的對(duì)等協(xié)作模式,原來剛性的指令執(zhí)行序列也轉(zhuǎn)變?yōu)橛山M件節(jié)點(diǎn)相互協(xié)作構(gòu)成的消息流程圖。

實(shí)際這就是Node-RED構(gòu)建應(yīng)用和實(shí)現(xiàn)功能的基本方式,但其中重要的區(qū)別在于,節(jié)點(diǎn)之間的協(xié)作并不是指令式的,而是聲明式的。也就是說,各個(gè)節(jié)點(diǎn)并不關(guān)心所連接節(jié)點(diǎn)的具體類型、功能和特性,它的任務(wù)僅僅是接收消息、處理消息和發(fā)送消息,不負(fù)責(zé)對(duì)所發(fā)消息的用法做具體要求和詳細(xì)規(guī)定。因此,Node-RED節(jié)點(diǎn)不必對(duì)外暴露其具體的功能和特性。節(jié)點(diǎn)之間發(fā)送的消息只是純粹的數(shù)據(jù),不必承載明確的指令和意圖。節(jié)點(diǎn)之間只是依從數(shù)據(jù)交換和處理的需要相互連接,不必因某種邏輯關(guān)系而強(qiáng)制綁定。通常我們把這種編程方式叫做基于流程或數(shù)據(jù)流的編程模式。

三、環(huán)境

Node-RED的安裝方法和過程都非常簡(jiǎn)單,概括說就只有兩步:第一,下載(https:///en/download/ )并安裝Node.js;第二,利用Node.js中的npm,安裝Node-RED。

安裝完成后,只要在命令行窗口中輸入執(zhí)行node-red,就可以啟動(dòng)整個(gè)Node-RED系統(tǒng)。這時(shí),如果將瀏覽器指向運(yùn)行Node-RED的主機(jī)地址和端口(默認(rèn)為1880),即可進(jìn)入其開發(fā)環(huán)境界面。

打開后的開發(fā)環(huán)境一般包括六個(gè)主體功能單元,分別為:1) 節(jié)點(diǎn)面板,用于顯示所有開發(fā)可用的節(jié)點(diǎn)類型;2) 流程面板,用于為開發(fā)者提供連接節(jié)點(diǎn)、創(chuàng)建和編輯流程等功能;3) 信息面板,用于顯示節(jié)點(diǎn)的詳細(xì)規(guī)格信息;4) 調(diào)試面板,用于顯示流程運(yùn)行過程中產(chǎn)生的調(diào)試信息;5) 編輯面板,用于設(shè)置節(jié)點(diǎn)的屬性行為,主要包括消息內(nèi)容的修改、轉(zhuǎn)換和處理等;6) 部署按鈕系統(tǒng)菜單,用于流程的部署運(yùn)行以及整個(gè)開發(fā)環(huán)境的配置管理。

Node-RED應(yīng)用開發(fā)的一般過程是,首先將所需的節(jié)點(diǎn)從節(jié)點(diǎn)面板中拖入流程面板,然后根據(jù)需要分別雙擊各個(gè)節(jié)點(diǎn),并在彈出的編輯面板中設(shè)置其屬性和行為。設(shè)置完成后,按數(shù)據(jù)流向和業(yè)務(wù)邏輯要求,以拖拽方式將流程面板中的相關(guān)節(jié)點(diǎn)組合連接起來,形成業(yè)務(wù)和數(shù)據(jù)流程。最后點(diǎn)擊部署按鈕,將設(shè)計(jì)好的流程部署到Node-RED服務(wù)器上運(yùn)行。簡(jiǎn)單說就是,添加節(jié)點(diǎn)、設(shè)置節(jié)點(diǎn)連接節(jié)點(diǎn)部署運(yùn)行四步(具體順序可根據(jù)情況進(jìn)行適當(dāng)調(diào)整),更詳細(xì)的步驟和說明請(qǐng)大家自行參考Node-RED官網(wǎng)(https:// )或17coding的Node-RED子站(https://nodered. )。

四、實(shí)現(xiàn)

讓我們重新回到TinyWebDB的開發(fā)和實(shí)現(xiàn)上來。在上一篇關(guān)于TinyWebDB客戶端的分析中,我們提到,其每項(xiàng)功能都涉及到了發(fā)送服務(wù)請(qǐng)求接收返回結(jié)果這兩個(gè)過程,從數(shù)據(jù)流向看,一個(gè)為數(shù)據(jù)輸出,另一個(gè)則為數(shù)據(jù)輸入。因此,我們?cè)诤笈_(tái)服務(wù)的設(shè)計(jì)上,也需要有相應(yīng)的節(jié)點(diǎn)與之對(duì)接。比如,對(duì)應(yīng)于前端的發(fā)送服務(wù)請(qǐng)求,后端應(yīng)該有個(gè)偵聽服務(wù)請(qǐng)求節(jié)點(diǎn);對(duì)應(yīng)于前端的接受返回結(jié)果,后端應(yīng)該有個(gè)發(fā)送返回結(jié)果節(jié)點(diǎn)。這就像兩個(gè)人之間對(duì)話交流,一個(gè)人用嘴傾訴時(shí),需要另一個(gè)人用耳朵聆聽,反之亦然。

1) 初步設(shè)計(jì)

根據(jù)上面的分析,我們應(yīng)首先針對(duì)storeavalue和getvalue這兩項(xiàng)功能,向Node-RED的流程面板中分別拖入兩組輸入、輸出節(jié)點(diǎn)。由于我們采用的是標(biāo)準(zhǔn)的HTTP通信協(xié)議,所以在類型上,應(yīng)該選擇和使用節(jié)點(diǎn)面板中的http in(HTTP輸入)和http response(HTTP輸出)節(jié)點(diǎn),分別對(duì)應(yīng)于數(shù)據(jù)通信中的請(qǐng)求(Request)和應(yīng)答(Response)功能。

值得注意的是,請(qǐng)求和應(yīng)答之間必須具有一定的綁定性和關(guān)聯(lián)性,即我們常說的所問即所答,如此才能保證通信的成功。因此,我們要先將同組的輸入、輸出節(jié)點(diǎn)用消息線連接起來,這樣就可以確保二者所針對(duì)的通信對(duì)象具有一致性,避免通信過程中出現(xiàn)偏差。

另外,為了在開發(fā)過程中測(cè)試和調(diào)試的方便,我們還要再加入兩個(gè)debug(調(diào)試)節(jié)點(diǎn),分別連接到兩個(gè)功能組的http in節(jié)點(diǎn)上,這樣就能使接收到的外部消息被同時(shí)傳送并顯示到調(diào)試面板上,以驗(yàn)證接收功能的正確性。

在進(jìn)行正式的開發(fā)、設(shè)置之前,有必要先對(duì)流程中各節(jié)點(diǎn)進(jìn)行統(tǒng)一命名,突出其作用和功能,以方便開發(fā)過程中的管理、跟蹤和調(diào)試。

之后,我們才按照TinyWebDB通信協(xié)議的約定,對(duì)http in節(jié)點(diǎn)中與通信相關(guān)的屬性進(jìn)行設(shè)置,主要包括通信方法和偵聽地址這兩項(xiàng)。對(duì)照上一篇文章中的相關(guān)說明,應(yīng)分別進(jìn)行如下設(shè)置。

設(shè)置完成后,點(diǎn)擊右上角的部署按鈕,將設(shè)置好的節(jié)點(diǎn)和流程部署到Node-RED系統(tǒng)中運(yùn)行。這樣,我們所設(shè)計(jì)的流程就初步具備接收前端數(shù)據(jù)的能力了。

2) 驗(yàn)證成果

為驗(yàn)證設(shè)計(jì)成果,我們還是先利用App Inventor編寫一段簡(jiǎn)單的測(cè)試代碼。其中,出于簡(jiǎn)化功能的需要,我們?cè)跍y(cè)試數(shù)據(jù)部分,特意采用了硬編碼的方式。

執(zhí)行這段代碼后,我們就能在Node-RED調(diào)試面板中看到以下數(shù)據(jù)內(nèi)容。

恰好與前端應(yīng)用所提交的數(shù)據(jù)能夠?qū)?yīng)起來,這說明我們所設(shè)計(jì)的服務(wù)已經(jīng)能成功接收前端所發(fā)送的數(shù)據(jù)了。只不過在數(shù)據(jù)形式上,它使用了JavaScript對(duì)象類型的表示形式,除了所使用的符號(hào)有些差異外,實(shí)際它基本可以等同于App Inventor中的鍵值對(duì)列表。

3) 糾正錯(cuò)誤

我們?cè)賮砜匆幌虑岸薃pp Inventor一側(cè)的測(cè)試結(jié)果。

通過對(duì)結(jié)果做簡(jiǎn)單分析,不難看出,TinyWebDB組件對(duì)于保存數(shù)據(jù)功能的返回結(jié)果是不進(jìn)行內(nèi)容驗(yàn)證的,只要有結(jié)果就算調(diào)用成功,所以彈出了正確提示。而查詢數(shù)據(jù)功能則相反,由于我們沒有按約定返回列表字串形式的結(jié)果(即JavaScript形式的[VALUE, tag值, value值]),所以出現(xiàn)了解析錯(cuò)誤。

另外,如果與調(diào)試面板中出現(xiàn)的信息進(jìn)行對(duì)比,還可以發(fā)現(xiàn),輸入、輸出數(shù)據(jù)的有效成分是被封裝在消息對(duì)象的payload(載荷)屬性之中,其作用有點(diǎn)類似于電子郵件中的正文。而像請(qǐng)求對(duì)象、應(yīng)答對(duì)象等與網(wǎng)絡(luò)通信相關(guān)的其他內(nèi)容,則放置在payload之外其他屬性中,就像電子郵件中的發(fā)送者和接收者等。為了證明這一點(diǎn),我們可以將debug節(jié)點(diǎn)的輸出屬性修改為“完整消息對(duì)象”,然后再來看一下調(diào)試面板中出現(xiàn)的結(jié)果。

實(shí)際在完整的Node-RED消息對(duì)象結(jié)構(gòu)中,_msgid和payload是兩個(gè)必備的主要成分,前者像身份證編號(hào)一樣,是消息的唯一性標(biāo)識(shí),而后者則承載了消息的主體內(nèi)容,其他則是在此基礎(chǔ)上根據(jù)功能需要進(jìn)行的擴(kuò)展,比如上圖中的req和res屬性。流程中的各個(gè)節(jié)點(diǎn)之所以能夠相互連接成為一個(gè)整體,其重要的原因在于它們之間所傳送的消息具有一致性,即_msgid必須保持相同,而我們通常所說的消息處理和轉(zhuǎn)換其實(shí)是指對(duì)同一消息payload部分的處理和轉(zhuǎn)換。

如果要解決前端出現(xiàn)的錯(cuò)誤提示問題,我們必須在現(xiàn)有的流程中增加適當(dāng)?shù)奶幚砉?jié)點(diǎn),將發(fā)往http response節(jié)點(diǎn)消息的payload內(nèi)容修改為符合TinyWebDB通信協(xié)議要求的形式。這里,我們選擇節(jié)點(diǎn)面板中的template(模板)節(jié)點(diǎn)來完成這一使命。

各節(jié)點(diǎn)屬性的具體設(shè)置如下圖所示。暫時(shí)我們將返回結(jié)果也設(shè)為硬編碼形式,以方便驗(yàn)證解決問題的效果。

重新測(cè)試后的結(jié)果如下圖所示。

應(yīng)該說,從輸出消息的角度看,基本解決了上面的問題。但是如果看一下調(diào)試面板中的信息,不難發(fā)現(xiàn),由于采用了硬編碼的方式,所以這樣的測(cè)試結(jié)果,實(shí)際和前端的輸入沒有任何關(guān)系,我們需要進(jìn)一步改進(jìn)我們的設(shè)計(jì),增加相應(yīng)的處理節(jié)點(diǎn)。

4) 改進(jìn)設(shè)計(jì)

首先,我們需要將前端發(fā)送的請(qǐng)求數(shù)據(jù)信息以某種方式保存起來,使兩個(gè)功能流程及其中相關(guān)處理節(jié)點(diǎn)之間能夠?qū)崿F(xiàn)數(shù)據(jù)分享。我們知道常規(guī)的數(shù)據(jù)存儲(chǔ)方式包括變量存儲(chǔ)、文件存儲(chǔ)和數(shù)據(jù)庫存儲(chǔ)等,由于我們的設(shè)計(jì)目標(biāo)是最簡(jiǎn)系統(tǒng),所以暫時(shí)選擇最簡(jiǎn)單的變量存儲(chǔ)方式,以后需要時(shí)再根據(jù)情況逐漸擴(kuò)展到其他存儲(chǔ)方式。

在Node-Red中,系統(tǒng)性的環(huán)境變量包括節(jié)點(diǎn)(context)、流程(flow)和全局(global)等三種類型,分別對(duì)應(yīng)于同一節(jié)點(diǎn)內(nèi)、同一流程標(biāo)簽內(nèi)以及整個(gè)開發(fā)環(huán)境等三類不同范圍的作用域。由于我們目前的設(shè)計(jì)對(duì)象是基于同一系統(tǒng)的不同功能,所以采用流程變量會(huì)更適合一些。

系統(tǒng)預(yù)設(shè)的流程變量名為flow,因此,我們可以將所需的存儲(chǔ)對(duì)象設(shè)為flow.tinywebdb,如果有些讀者對(duì)JavaScript對(duì)象類型不太熟悉的話,不妨把它想像成我們?cè)贏pp Inventor中所創(chuàng)建的鍵值對(duì)類型變量。

具體做法是,在節(jié)點(diǎn)面板中選取change(修改)節(jié)點(diǎn),將其加入storeavalue流程,并通過屬性設(shè)置功能,對(duì)該存儲(chǔ)對(duì)象進(jìn)行命名和賦值,也就是將http in節(jié)點(diǎn)接收到的前端數(shù)據(jù)保存到該對(duì)象中。

同時(shí),在getvalue流程中增加switch(切換)節(jié)點(diǎn),將http in節(jié)點(diǎn)接收消息中的payload屬性值與存儲(chǔ)對(duì)象的對(duì)應(yīng)值進(jìn)行比較,根據(jù)比較結(jié)果將流程切換到不同的返回結(jié)果處理分支上。

最后,再統(tǒng)一修改兩個(gè)流程中所有生成返回結(jié)果的template節(jié)點(diǎn),將相關(guān)變量以模板方式嵌入到其輸出消息的payload屬性值中。其中的{{{...}}}符號(hào)表示,要在輸出時(shí)用其中所包圍變量的當(dāng)前值替換這部分占位內(nèi)容,比如如果a的值為1,那么{{{a}}}的輸出結(jié)果就為1。

至此,我們就完成了最簡(jiǎn)TinyWebDB系統(tǒng)的全部設(shè)計(jì)工作,最后形成的完整數(shù)據(jù)和業(yè)務(wù)流程如下圖所示。

五、測(cè)試

首先,我們來設(shè)定一組中文測(cè)試數(shù)據(jù)。

通過執(zhí)行測(cè)試代碼,將其保存到TinyWenDB中。

然后,設(shè)置查詢條件。

再次執(zhí)行測(cè)試代碼,向TinyWebDB提交查詢請(qǐng)求,并獲取相關(guān)數(shù)據(jù),以驗(yàn)證保存效果。

接著,我們?cè)俑淖円幌虏樵儣l件。

看看TinyWebDB是否能正常返回空記錄。

經(jīng)簡(jiǎn)單測(cè)試驗(yàn)證,所設(shè)計(jì)的系統(tǒng)基本實(shí)現(xiàn)了預(yù)期的目標(biāo)。盡管從系統(tǒng)功能上看還十分簡(jiǎn)陋,技術(shù)細(xì)節(jié)上考慮得也不是很周全,而且所能保存的數(shù)據(jù)也非常有限,且無法實(shí)現(xiàn)持久化存儲(chǔ),但俗話說的好,萬丈高樓平地起,一切復(fù)雜的應(yīng)用和擴(kuò)展其實(shí)都是在這類看似簡(jiǎn)單的原型基礎(chǔ)之上逐步搭建起來的。我們將在后續(xù)的文章中,以此為基礎(chǔ),陸續(xù)向大家介紹一些與應(yīng)用和功能擴(kuò)展方面有關(guān)的內(nèi)容和實(shí)例。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多