
2015-08-13 | &nbs₹¥p; 發布者:梁國(guó)芳< | 查•≥看(kàn):3320次
IT新聞定義應用(yòng)的(de)使用(yòng)範圍
還(hái)有(yǒu)什(shén)麽比現(xiàn)學<"現(xiàn)用(yòng)更好(hǎo)的(de)學習(xí→★♥✘)方式呢(ne)?立即拿(ná)兩個(gè)項目練手吧(ba)!在優秀貢£↑↑¶獻者的(de)幫助下(xià),我們開(kāi)發了(le)Clog,±它是(shì)一(yī)個(gè)根據Git曆史提交生(s★βΩ∞hēng)成美(měi)觀的(de)更新日(rì)志(zhì)δ"γ£(changelog)的(de)小(xiǎo)工(≥gōng)具。Clog按照(zhào)Angular的(de)約定格式來(láαε★i)解析提交信息,這(zhè)種約定格式用(yòng)于大(®±•εdà)量流行(xíng)項目,諸如(rú£α):Angular、angular-translat♥e 、Hoodie 、Nickel 、Clap.rs等等。C$ log分(fēn)支于Node.js,開✔¶(kāi)始以傳統的(de)更新日(rì)志(zhì)項目為(wèi)基礎,≠↑後來(lái)有(yǒu)了(le)些(xiē)自®• (zì)己的(de)理(lǐ)念。
讓我們開(kāi)發一(yī)個(gè)網站(zhàn),從(có♥©πng)浏覽器(qì)就(jiù)能(néng)為(ε∞→wèi)任何GitHub公共倉庫生(shēng)成格式₩§♦良好(hǎo)的(de)更新日(rì)志(z¥↔₹↕hì),我們要(yào)在盡可(kě)能(néng)保持簡單的(d¥♣e)同時(shí)專注于重要(yào)的(de)部分(fēn)。
開(kāi)始我們的(de)Nickel應用(yòng)
本文(wén)假定你(nǐ)對(duì)Ruδ≈σst有(yǒu)基本的(de)了(le)解,如(rú)果你(nǐ)之前£↑™φ從(cóng)未用(yòng)Rust編寫任何東(d✔ōng)西(xī),官方《Rust Book》的(de)入門(mén)部分(fēn)能(néng)回答(dá)所有(yǒu)的(de)基本問(w∏©®èn)題。
啓動一(yī)個(gè)Rust項目最簡單的(de)方式就(jiù)是(shìσ×™)使用(yòng)官方的(de)包管理(lǐ)器(qì)Cargo。
這(zhè)條命令會(huì)創建一(yī)個(gè)新↑✘的(de)目錄clog-website,裡(lǐ)面包 ↕含一(yī)個(gè)“Hello World&rdq∑≤uo;應用(yòng),我們可(kě)以通(tōng)≥β過以下(xià)的(de)命令編譯和(hé)運行(xín↔↑∏↔g)這(zhè)個(gè)應用(yòng):
為(wèi)了(le)使用(yòng)Nickel,首先我們λ需要(yào)在Cargo.toml将其添為(wèi)依賴項,此時(shí€Ω←")Cargo.toml應該是(shì)這(zhè)樣的(de):
現(xiàn)在,Nickel已經添加為(wèi)一(yī)個(gα☆$←è)依賴項,我們嘗試讓服務器(qì)對(duì)于任何請(qǐng)求都(d 'ōu)返回一(yī)個(gè)“Hello World&rdq'≠uo;,使用(yòng)下(xià)面的(de)代碼替換main.rs♥£中的(de)內(nèi)容:
然而,當我們嘗試使用(yòng)“Car ↑go run”命令運行(xíng)應≠φ用(yòng)程序的(de)時(shí)候,出現(xi♥>±àn)了(le)下(xià)面的(de)錯(cuò)✔σ"₹誤:
其中的(de)原因很(hěn)簡單,雖然HTTP動詞處理(lǐ)器(qì)(HTTP Verb hand↕↕ler)已經注冊了(le)get,、put、 ∞λpost、 delete這(zhè)些(xiē)處理(lǐ)方法,且似乎≤→"直接存在于Nickel::()new返回的(de)Nickel對¥↑≠π(duì)象中,但(dàn)實際上(shàng),這(φ£♠ zhè)些(xiē)方法都(dōu)是(shì)Htt"pRouter特性(trait)在Nickel對(duì)φ 象中的(de)實現(xiàn)。
特性 (traits) 是(shì)Rust語言中一(yī∞♣εσ)個(gè)非常強大(dà)的(de)概念,詳&細解釋它超出了(le)本文(wén)的(de•λ★∏)範圍,如(rú)果你(nǐ)還(hái)沒有(yǒu)完全領會(huì↕₹)它們,我建議(yì)你(nǐ)從(cóng)頭讀(♠₩βdú)一(yī)遍官方《Rust Book》的(de)特性 (traits) ×↕章(zhāng)節。
幸運的(de)是(shì)Rust的(de)編譯♥≥器(qì)足夠智能(néng),這(zhè<≥γ)裡(lǐ)給了(le)我們正确的(de)提示,我們需要(yà↓'≤o)把HttpRouter特性引用(yòng)進當前作(zuò)用(yòng)₩★域,因為(wèi)Nickel在頂層模塊中暴露出Ht♠§tpRouter特性,所以我們隻需簡單更改,就'→↔(jiù)能(néng)将其引入作(zuò)用(yòn ♣g)域。
一(yī)旦我們将其引進作(zuò)用(yòng)域β♠π,Nickel對(duì)象的(de)方法就(jiù)變得(de)可(kě)用Ωε(yòng),你(nǐ)可(kě)以認為(wèi)它是(←₽§shì)擴展方法。
我們修複這(zhè)個(gè)問(wèn)題以後,再通(t★∞ōng)過“Cargo run”命φ↓±令運行(xíng)我們的(de)服務器(qì),在浏覽器(qλ"¥ì)中打開(kāi)http://127.0.0.1:6767就(jiù)可(kě)以看(kàn)到(dào)&ldqu₽♦o;Hello from Nickel”。這(zhè)不 ¥(bù)會(huì)太驚奇,對(duì)嗎(ma)?
生(shēng)成更新日(rì)志(zhì)
為(wèi)了(le)生(shēng)成我們的(de)第一(yī)份更☆↔→≥新日(rì)志(zhì),需要(yào)做(zuò)三件 ≥(jiàn)事(shì):
為(wèi)了(le)實現(xiàn)下(xià)載部分(fēn),我們創'≠β建一(yī)個(gè)名為(wèi)git.rs的(de)文(wén)件(jδ☆'£iàn),包含以下(xià)的(de)內(nèi)容:
我們不(bù)會(huì)逐行(xíng)講解代碼,通(tōng↑≈•)過方法标記,我們就(jiù)可(kě)以清楚的(de)理(lǐ)解π £,第一(yī)個(gè)參數(shù)指定要(yào)克隆Git倉庫的(de)↕×π&URI,第二個(gè)參數(shù)指定存放(fàng)路(l£<☆₹ù)徑。返回一(yī)個(gè)Resu↔δ✔lt<String, Error> ,要(yào)麽是(shì)一(yī)個(gè)發送到(dào)标₹♣準輸出(stdout)的(de)攜帶信息的(de)字δ∏符串(String),要(yào)麽是(shì)✘一(yī)個(gè)發送到(dào)标準錯(cuò>®)誤(stderr)的(de)攜帶信息的(de)字符串錯(cuò)誤(Err↕&∏or)。
在我們使用(yòng)之前,需要(yào)編寫 £與Clog交互的(de)代碼,我們創建一±✔₹←(yī)個(gè)名為(wèi)clog€↕_interop.rs的(de)文(wén)件(j≈φφiàn),包含以下(xià)內(nèi)容:
用(yòng)這(zhè)個(gè)方法獲取一(yī)個(gè)&a←®₹mp;str類型的(de)本地(dì)Git倉©↕±©庫路(lù)徑和(hé)一(yī)個(g ←è)GitHub的(de)URL,Clog生(shē≈←✔&ng)成鏈接時(shí)需要(yào)知(z ™hī)道(dào)GitHub的(de)URL,這(zhè)個(gè)方法會₩ (huì)生(shēng)産markdown格式∞>σ&的(de)更新日(rì)志(zhì),通(t§∞↔ōng)過String類型返回,并且會(huì)在π 生(shēng)成更新日(rì)志(zh©÷ì)後馬上(shàng)删除本地(dì)Git庫。
直到(dào)現(xiàn)在,我們構建了(le)基本代碼塊來☆β→®(lái)生(shēng)成我們的(de)第一(yī)個≤α(gè)更新日(rì)志(zhì),main.rs文(wΩén)件(jiàn)看(kàn)起來(lái)像這(zhè)樣ε€:
此處對(duì)代碼做(zuò)一(yī)$¶些(xiē)說(shuō)明(míng),為(wèi★←)了(le)使用(yòng)Clog,我們需要•<±(yào)像之前添加Nickel一(yī)樣将Clog添加到(dào)♦♠λCargo.toml,然後添加“exter€←Ωn crate clog”語句。我們還(há✔♣→↑i)需要(yào)添加git模塊和(hé)clog_interop模塊,為(w ≈±∏èi)了(le)讓編譯器(qì)能(néng)✘♣ 包含這(zhè)些(xiē)模塊,我們需要(yào)把這(zhè)兩個(gè÷☆)Rust文(wén)件(jiàn)放(fàng)進我們的(de)工(g±π¶≠ōng)程目錄中。
其餘的(de)相(xiàng)當明(míng)了(l✔✘×e),我們硬編碼(hardcode)repo_uri來($± lái)獲取Angular 2的(de)儲存庫,克隆到(dào)本地(dì)&→♥ldquo;some-uniqe-id”目錄。這 ×(zhè)些(xiē)下(xià)一(yī)步做(zuò)好(hσ§ǎo)準備。
最有(yǒu)趣的(de)部分(fēn)是☆↑(shì)使用(yòng)middlewa¶×¶re!對(duì)每次請(qǐng)求都(dōu)把&a∏→≥mp;changelog轉換為(wèi)&a≈∑≥<mp;str然後返回。
很(hěn)多(duō)新人(rén)在這(zhè$φ)裡(lǐ)會(huì)有(yǒu)共同的(de←βΩ)疑惑,但(dàn)Nickel團隊的(de)Ryman在此 做(zuò)了(le)一(yī)個(gè)很(hěn)好(πhǎo)的(de)解釋。
大(dà)意是(shì)程序會(huì)在每一(♦"yī)個(gè)請(qǐng)求到(dào)來(lái)時(shí)被調λ§₩★用(yòng),而你(nǐ)不(bù)能(néng)轉移(β®所有(yǒu)權)String,因為(wèi)隻能(nén®<g)被轉移一(yī)次。
如(rú)果我們重新運行(xíng)服務器(qì),并在浏覽器(qì)中打開λΩ&(kāi)網頁,将看(kàn)到(dào)這(zhè)個(gè♦♥®)樣子(zǐ):
萬歲!這(zhè)是(shì)Angular 2項目markdown €∞格式的(de)更新日(rì)志(zhì)。
使用(yòng)JSON數(shù)據
現(xiàn)在我們已經用(yòng)服務器(qì)克隆代•×$碼庫,生(shēng)成markdown格式的(de)更新日(rì)志(zhì&δ♥),然後返回給我們的(de)浏覽器(qì),目•♥₹前還(hái)不(bù)錯(cuò)。為(wèi)了(le)使其更好(hǎ₹♥≈o)更靈活,我們需要(yào)創建合适的(π¶de)JSON API讓前端使用(yòng)。
我們勾勒一(yī)下(xià)JSON請(qǐng)求和(hé)響應≠φ的(de)樣子(zǐ):
Request Object
目前,我們除了(le)repository之外(wài)不(λγbù)需要(yào)其他(tā)任何東(dōng÷€φ♠)西(xī)。然而,我們以後可(kě)能(néng)添加諸如(β♠↑rú)version_name和(hé)σ subtitle來(lái)為(wèi)前端暴露其他★σ×(tā)功能(néng)。
Response Object
同樣也(yě)讓響應保持簡單,除了(le)changelog之外(₽σ₽wài)和(hé)防止非正常工(gōng)作(πα ↑zuò)的(de)error信息之外(wài)≠ §,不(bù)再需要(yào)其他(tā)東(dōng)西(xδ©↑&ī)。
為(wèi)了(le)接受和(hé)返回JSON對(duì)象,首先需要(yà↓←≥o)創建新的(de)structs,命名為(wèi)ClogC★→onfig和(hé)ClogResult,并且分(fēn)别創 ©>建文(wén)件(jiàn)clog_config.rs和(hé)clog_®εresult.rs。
clog_config.rs
clog_result.rs
為(wèi)了(le)避免進行(xíng)手動J↑ SON解析和(hé)格式化(huà)代碼,可(kě)以讓Rust≤±€為(wèi)我們自(zì)動實現(xiàn≈β♠)RustcDecodable 和(hé) Rustc®$♥Encodable特性。
有(yǒu)了(le)這(zhè)兩個(gè)結構,我們來(lá→<i)編寫能(néng)接受和(hé)返回JSON結構的(de)POST處理(l★ǐ)器(qì)。
我們來(lái)看(kàn)看(kàn)這(zhè)個(gè)代∑<β碼,使用(yòng)server.post注冊一(±→yī)個(gè)處理(lǐ)器(qì)來(l"€±→ái)應答(dá)/generate路(₽♥'εlù)由下(xià)的(de)POST請(qǐng)求。之前我們用(↑ σδyòng)一(yī)個(gè)簡單的(d e)字符串來(lái)使用(yòng)middleε∏'ware宏,現(xiàn)在我們使用(yòng)的(de)是(sh♠→ ♠ì)塊語法的(de)形式,讓處理(lǐ)器(qì)能(néng)訪問(≤¶wèn)request和(hé)response對(♠§↓duì)象。
Nickel支持使用(yòng)json_as方法來(✘γ☆πlái)解析JSON體(tǐ)。美(měi)中不(bù)足的(de)是(s €¥hì),和(hé)HttpRouter一(yī)樣,使用(yòng)它的(¥>↓de)功能(néng)時(shí)需要(&↔<÷yào)将JsonBody特性引入作(zuò)用(yòng)域>∑α↔目前還(hái)不(bù)要(yào)分(fēn)心,稍後¶®∏再看(kàn)需要(yào)引入的(de)所有(yǒu)模塊。
我們将JSON解析為(wèi)ClogConfig對✘Ω§(duì)象的(de)實例,由clog_config持有(yǒu)這(zh₽₽✘∏è)個(gè)實例,進一(yī)步嘗試克隆這(zhè)個(gè)給定的(d¶®↑e)repository。現(xiàn)在沒有(yǒu)再将一§♦≥★(yī)個(gè)庫硬編碼進去(qù),我們α¥需要(yào)規劃因為(wèi)拼寫錯(cu'δò)誤或其他(tā)原因導緻克隆一(yī)個($Ωgè)庫失敗之後的(de)解決方法。如(ε λrú)果克隆失敗,我們簡單的(de)設置ch→"↔ angelog為(wèi)空(kōng)字符串≥∞,并将error設置為(wèi)返回的(de)錯(cuò)誤信息。
如(rú)果克隆成功,我們如(rú)之前那(nà)樣生(shēng)成更新日♥∏(rì)志(zhì)從(cóng)而設置ch÷λ§angelog和(hé)error,注意Rust中if/else結構也↑¥↓α(yě)是(shì)基于表達式,所以我們才可(kě)↔¶↕以使用(yòng)如(rú)此簡潔的(de)寫法,将let result <•= 置于if之前。
同樣重要(yào)的(de)是(shì),在返回給調用(yòng)者之前,★≥$我們需要(yào)使用(yòng)json::encode将CΩ&logResult對(duì)象轉換成JSON格式。
這(zhè)組新代碼還(hái)少(shǎo)了(le)很(hěn)♥♦>重要(yào)的(de)一(yī)部分( ₩fēn),我們必須調整導入的(de)模塊和(hé)Cargo.toml中的(d↑₹₹✔e)依賴項。
最讓人(rén)詫異的(de)是(shì)目前對(duì)JSON的(dπ¶>e)支持沒有(yǒu)放(fàng)到(dào)±∑™标準庫,而是(shì)被拉取到(dào)rustc-serβ∞♦¶ialize庫。另外(wài),在Rust代碼中使用(yòng)下(x↑ε≈ià)劃線時(shí),還(hái)要(yào)在Carβλ✔go.toml中增加rustc-serialize = &ldquδ÷σo;*”。
現(xiàn)在可(kě)以用(yòng)curl≈₩嘗試我們的(de)API了(le)。
目前還(hái)是(shì)有(yǒu)一(yī)個(ε→≠gè)很(hěn)大(dà)的(de)缺陷,對(duì)于每一(yī)≥¶個(gè)請(qǐng)求,我們克隆到(dào)一(yī)個(gè)↕<叫some-uniqe-id的(de)目錄中去(qù),但(dànβ≈)如(rú)果API同時(shí)接受兩個(gè<δ)請(qǐng)求,程序就(jiù)會(huì) φ出問(wèn)題。為(wèi)了(le)讓我們克隆的(de)↔>目錄使用(yòng)到(dào)真正唯一(yī)的(de)名字,我們來(lá≥♥πi)修改代碼,添加一(yī)個(gè)名為(wèiβ≤)uuid的(de)包(crate)。
uuid包添加以後,修複這(zhè)個(gè)問•£≈♦(wèn)題變得(de)非常簡單,隻需要(↓€♣yào)将處理(lǐ)器(qì)內(nèi)部的(de)re¥±←po_name設置一(yī)下(xià)。
我們先不(bù)管這(zhè)裡(lǐ)引入α¶>Ω的(de)改變,如(rú)果你(nǐ)有(yǒu)什♦♦(shén)麽問(wèn)題,請(qǐng)随意跳(tiào)轉到(d∑φαào)最終方案 。
随著(zhe)這(zhè)個(gè)變化(huà),我們的(d©₩ e)API已經準備好(hǎo)投入使用(yòn ™↔g)。我們可(kě)以向提高(gāo)工(gōng) ✔'效的(de)方向做(zuò)一(yī)步改進,通(tōng)過σ>λ$解析器(qì)分(fēn)析庫名而避免鍵入整個(gè≥↑₩™)URL。這(zhè)将是(shì)最終✔ 的(de)解決辦法,但(dàn)我不(bù)打算(suàn)在這(zhè)₹≤裡(lǐ)涉及,畢竟它是(shì)一(y≈♦≈ī)個(gè)非常簡單的(de)步驟。
為(wèi)前端服務
現(xiàn)在我們有(yǒu)了(le)API,隻需®≤↕±要(yào)一(yī)個(gè)簡單的(de)前端提供最基本★₩的(de)使用(yòng)。如(rú)果我們的(de)目标是(shì<)合适的(de)可(kě)拓展方案,我們服務∑ε₽•的(de)前端可(kě)能(néng)不(bù)會(huì)和(hé)提©♦☆✘供API服務的(de)服務器(qì)是(shì)同一( yī)個(gè)。我們這(zhè)篇博文(wén)的(de)目的(de)§®♣是(shì)展示Nickel的(de)功能(nén®ααg),這(zhè)裡(lǐ)僅僅為(wèi)了(le)保證項♥π目的(de)完整性。
對(duì)于前端,我們不(bù)會(huì)涉≠✘及得(de)像後端那(nà)麽深,跳(tiào)轉到(dào ©÷₩)GItHub的(de)庫 , 這(zhè)個(gè)庫 包含了(le)這(zhè)篇文(wén)章(zhāng)的(de)所有(÷<yǒu)代碼。
讓我們姑且認為(wèi)我們正在建設一(yī)個(gè)簡單的♥¶(de)Web應用(yòng)程序,一(y±×"αī)個(gè)為(wèi)用(yòng)戶輸入GitHub上(shσσβàng)倉庫網址的(de)文(wén)本框,和(hé)一(yī)個(g¶α₹←è)從(cóng)我們構建的(de)API請(qǐng)α₹↕求變更的(de)按鈕。
為(wèi)了(le)服務于前端,我們創建一(yī)個(gè)assets目">£錄,其中包含css、js、templates子( ♠₩<zǐ)目錄,将index.html放(fà¶₹λng)置在templates目錄,其中包含的(de)Javascr✘<ipt文(wén)件(jiàn)和(hé)CS€ S文(wén)件(jiàn)分(fēn)别放(fàng)置js和(hé)css×↕•目錄。
為(wèi)了(le)能(néng)為(wèi)前端服務,我們還(hái)必'←須告訴Nickel那(nà)些(xiē)靜(jìng)态服務器(qì"σ≠)文(wén)件(jiàn)。
我們分(fēn)别挂載assets和(hé)assets/φ♠≥♦templates,以便在頂層目錄中訪問(wèn)i♣ndex.html,但(dàn)是(shì)Ja₽¶βvascript和(hé)CSS還(hái)是€≥↔₽(shì)通(tōng)過子(zǐ)目錄訪問(wèn)。π§

現(xiàn)在有(yǒu)一(yī)個(gè)可(↑Ωkě)以運行(xíng)的(de)網站(λ∞zhàn)了(le)。
把應用(yòng)部署到(dào)Heroku
但(dàn)是(shì)現(xiàn)在我們的(de)應用(yòng)↔₹僅僅很(hěn)好(hǎo)的(de)運行(xíng)在α©¥™我們的(de)開(kāi)發機(jī)上(shàng),如(βαrú)果能(néng)給世界看(kàn)看(kàn)不(bù)σβ→≥是(shì)更棒嗎(ma)?我們把他(tā<π )托管到(dào)Heroku上(shàng),托管一(yī)個(g€♠♥×è)Nickel應用(yòng)到(dào)Heroku非常簡單,如(rú)λ♣✔>果你(nǐ)之前從(cóng)未用(yòng)過Heroku,你(nǐ)需要☆β(yào)在他(tā)們的(de)網站(zhàn)上↔→'∑(shàng)注冊,并下(xià)載下(xià)一(yī)步将用(yòng)<≈到(dào)的(de)Heroku CLI tool。
一(yī)旦你(nǐ)安裝了(le)Heroku C✔LI并登錄,你(nǐ)可(kě)以通(tōng'£§£)過下(xià)面的(de)命令從(cóng)現(xiàn)有(y¥☆δǒu)資源庫創建應用(yòng)程序。
注意:Heroku将會(huì)使用(yòng)heroku creat¶€♦e命令的(de)第一(yī)個(gè)參數↑ ∞'(shù)作(zuò)為(wèi)站(zhàn)點的(de)子( ∞zǐ)域名。這(zhè)裡(lǐ)是(shì↕<∑€)http://demo-clog-website∑≠±.herokuapp.com.
這(zhè)将為(wèi)你(nǐ)的(de)庫增加一(yī)個(gèΩ)叫做(zuò)heroku的(de)Git遠(yuǎn)↑£™程分(fēn)支。部署站(zhàn)點僅僅是(shì)運∞≥φ行(xíng)git push heroku master命令那(nà)麽ε↔♠α簡單。
噢!我們的(de)應用(yòng)好(hǎo)像缺少≠≠€(shǎo)東(dōng)西(xī),H ✘§₩eroku拒絕構建這(zhè)個(gè)應用(yòng)。H↔→®σeroku能(néng)托管各種不(bù)同技(β♠jì)術(shù)棧的(de)應用(yòng→≥),通(tōng)過指定構建包(buildpack)來(lái)配置服務器★φ(qì),使其工(gōng)作(zuò)。我們創建應用(yòng)↓¥•×的(de)時(shí)候,設置的(de)是(shì)一(yα&βī)個(gè)非官方的(de)Rust構建包(但πΩ(dàn)是(shì)可(kě)用(yò♥←ng)),但(dàn)是(shì)還(hái)缺少(shǎo)兩種重要<✘λ (yào)的(de)文(wén)件(jiàn),♠÷<ε用(yòng)來(lái)提示Heroku應該如(rú₩γ)何對(duì)待我們的(de)程序。
RustConfig
RustConfig文(wén)件(jiàα©±εn)告訴構建包我們想用(yòng)哪個(gè)版本的(de)γ☆ Rust編譯器(qì)構建我們的(de)應用(yòng)。
Procfile
Procfile告訴Heroku調用(yòng)哪個(gè)命令來(l ♣Ωái)開(kāi)始這(zhè)個(gè)進程,因為(wèi)Cargo®π✘把可(kě)執行(xíng)文(wén)件€↔→♣(jiàn)放(fàng)在target/release/our-app-®σname,所以我們進行(xíng)對(du©Ωì)應的(de)設置。
創建并提交這(zhè)兩個(gè)文(wén)件(j®γ iàn)到(dào)我們的(de)庫之後,再次通(tōng)過git push£↓φ heroku master部署站(zh<↓γàn)點,這(zhè)次部署能(néng)正常運行(xín®☆ g),因此我們來(lái)檢查一(yī)下(xià)在線站(zhà$§₹n)點。

站(zhàn)點隻給出一(yī)個(gè)Heroku♣®γ通(tōng)用(yòng)的(de)錯(cuò)誤頁面,♦"↕©我們使用(yòng)heroku logs命令檢查一(yī)下(xià)輸$♥出。
從(cóng)日(rì)志(zhì)中,♦可(kě)以清晰的(de)看(kàn)到(dào),服務器(qì€φ♣)成功啓動,但(dàn)是(shì)在60秒(miǎ↔↔<¥o)後因為(wèi)綁定到(dào)$PORT端口不(bù)成功,超時(s™Ωhí)而關閉。
Heroku希望我們綁定他(tā)們在環境變量中指定的(dε↕♥e)随機(jī)端口号,然而我們可(kě)以使用(yòn$≤≈€g)硬編碼的(de)6767端口。
修複這(zhè)個(gè)問(wèn)題,隻需要β≈"←(yào)簡單的(de)從(cóng)環境變量中讀(←Ω•dú)取PORT,如(rú)果PORT不(b↓¥ù)存在,再默認綁定到(dào)6767。
修複好(hǎo)這(zhè)個(gè)問(→§§wèn)題後,網站(zhàn)就(jiù)可(kě)以正常運行(xíng★λ)了(le)。
你(nǐ)可(kě)以到(dào) demo-clog-website.herokuapp.com 進行(xíng)一(yī)些(xiē)嘗試。網'±₹←站(zhàn)包含前面提到(dào)的(de)UR§∑L解析器(qì)改善,因此輸入庫(repositorφ♥y)可(kě)以使用(yòng)user/repo的(★☆←de)形式。你(nǐ)可(kě)以在 "™;這(zhè)裡(lǐ)(GitHub) απ∞₽找到(dào)這(zhè)個(gè)演示項目的(de)全↕∞¥部代碼。
現(xiàn)在,是(shì)不(bù)是(shì)為(wèi)你(n ≤¶®ǐ)的(de)首個(gè)Nickel項目開(kāi)了(le)一(yī)個★φ(gè)好(hǎo)頭?