亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

使用Meteor配合Node.js編寫實時聊天應用的范例

2019-11-20 12:11:20
字體:
來源:轉載
供稿:網友

我經常見到被拿來與Derby.js做比較的框架是Meteor.js. 與Derby相似的是,它也能在多個客戶端下實時更新views, 盡管做法上可能跟Derby有點不同. Derby可以較容易的使用多種數據庫, 而Meteor則只親近于MongoDB. 事實上, 通過如Mongoose客戶端接入數據庫的API與你在服務端所期望的已經非常接近了.

雖然現在meteor是個有一些缺點和爭議的框架, 但Meteor看起來是非常有趣的選擇用來建立有實時需求的應用. 個人還是喜歡Derby基于傳統回調的編程形式更吸引我, 但在Derby的強大背后,卻缺乏健壯的文檔和一個大的開發者社區, 這無疑是個很大的打擊. 或許這會隨著時間推移而有所改變吧, 但比起Meteor來說還是會慢很多, 因為后者最近獲得了1100萬美元的資金. 這筆財政資金確保了Meteor的存在以及得到持續的支持. 對于那些需要財政與發展穩定的框架的開發者而言, 這筆資金只會讓Meteor更加優勝. <!-- more --> 今天,讓我們一起來看看如何新建一個真實的但又簡單的Meteor應用. 本質上說, 這是基于Tom的 Vimeo screencast的一個新手指引. 與Tom的 Vimeo screencast最大的不同是處理事件的方式. 比起復制粘貼一個Meteor示例的代碼, 我會一步一步的通過自己的方式來處理使用Enter鍵來提交一則訊息. 讓我們開始吧.

創建一個 Meteor應用

Derby和Meteor 他們共有的一個大加分是他們各自的命令行工具. 與Derby使用Node的內置的 npm 工具所不同的是, Meteor使用的是它自己的.

在終端(Mac OS X 和 Linux),執行如下的命令. (在這之前請確保你已經安裝了Node)

$curl https://install.meteor.com | /bin/sh

Metror會自己搞定,并安裝命令行工具.

要新建一個項目, 先轉到你的工作目錄然后運行下邊的代碼. 這會創建一個目錄, 里邊包括有Meteor和一個最基本模板程序.

$meteor create chat

現在, 你可以轉到該目錄并運行下面的代碼讓它跑起來

$cdchat$meteorRunning on: http://localhost:3000/

想要看到這個最基礎的應用程序, 你只需要在任意一款不過時的瀏覽器下打開http://localhost:3000/

只要你想, 你就可以使用Meteor內置的meteor deploy命令來部署你的應用到Meteor自己的服務器上

$meteor deploy my-app-name.meteor.com

只要你更新保存了你的代碼, 所有連接上的瀏覽器都會實時更新其頁面.

開發聊天應用

在Meteor Create指令產生的文件夾中,你可以看見不同的文件。如果你知道怎么查看隱藏文件的話,你還可以看見個.meteor這個文件夾。這個文件夾包含了Meteor它本身,以及MongoDB的數據文件。

在你App的根目錄文件夾下,你應該可以看到這三個文件:chat.html, chat.css和chat.js。這三個文件都是自帶說明部分的。HTML文件包含了App的模型以及外觀,他們都是被chat.css定義的。Javascript文件包含了在client和server端要執行的腳本。有一點很重要,不要把任何東西放進這個腳本文件,比如說配置參數和密碼,因為任何人都可以通過查看你應用程序的代碼看到這些。

用你喜歡的文本編輯軟件打開chat.js這個文件。就個人而言,我喜歡用Sublime Text2,因為這個工具簡潔還有多種鼠標狀態提示。

你可以在chat.js文件中查看到下面這樣一段代碼:
 

if (Meteor.is_client) { Template.hello.greeting = function () { return "Welcome to chat."; }; Template.hello.events = { 'click input' : function () { // template data, if any, is available in 'this' if (typeof console !== 'undefined') console.log("You pressed the button"); } }; } if (Meteor.is_server) { Meteor.startup(function () { // code to run on server at startup }); }

在Meteor.js中注意if段落中Meteor.is_client和Meteor.is_server的兩個部分。在這些區塊中的代碼會分開執行,當運行這段代碼的機器是client端則只運行clint塊中的代碼,server同理。這就說明了Meteor在實際運用中的代碼共享能力。

刪除掉if中所有Meteor.is_client和Meteor.is_server段的代碼,最后只剩下一段:
 

if (Meteor.is_client) { }

注意,當你保存了 腳本文件之后,你的瀏覽器會立刻刷新加載這段新的代碼。

創建視圖(View)

在我們正式對這個腳本文件動工之前, 我們需要先新建一個視圖用來展示聊天記錄. 在編輯器里打開chat.html并刪除body標簽里邊的代碼. 包括名為hello的template標簽.只留如下部分

<head> <title>chat</title></head><body></body>

接著在body標簽里添加下面這句

{{> entryfield}}

Meteor使用的模板系統與Mustache很相似.大括號{% raw %}{{}}{% endraw %}表示要呈現的內容. 通過簡單地在兩對大括號里添加內容如{% raw %}{{hello}}{% endraw %}, 模板系統會用hello這個變量的值來替換它. 后面會更詳細的介紹.

注意到了在entryfield這個詞前面有個大于號>了嗎? 使用該符號來指定渲染哪一個模板.

<template name="entryfield">  <input type="text" id="name" placeholder="Name" /> <input type="text" id="message" placeholder="Your Message" /></template>

在這個例子中,template標簽有單個屬性, 即模板的名字, 這就是我們要渲染的模板, 注意, 模板的名字要和body里的代碼指定的模板名字一樣 ({{> entryfield}})


查看瀏覽器, 你會發現頁面已經刷新了, 輸入框已經呈現出來了.

接下來, 在body里邊添加另外的一個mutache標簽用以渲染訊息列表

{{> messages}}

最后, 我們還需要新建一個名叫messages的模板. 在entryfield模板下面添加下面這段代碼

<template name="messages">  <p>    {{#each messages}}      <strong>{{name}}</strong>- {{message}}    {{/each}}  </p></template>

注意到each子句. 在Meteor中你可以使用如下的語法來遍歷一個數組模板

{{#each [name of array]}}{{/each}}

使用each循環時,上下文會有所改變. 當引用變量的時候, 實際上你引用的是每一個數組元素的值.

 例如,在我們的chat應用中, 我們遍歷了數組模板"messages"里邊的每個元素, 該數組可以像下面這樣,

[  {    "name": "Andrew",    "message": "Hello world!"  },  {    "name": "Bob",    "message": "Hey, Andrew!""  }]

然后, 在each循環中, 你可以看到{% raw %}{{message}}{% endraw %}{% raw %}{{name}}{% endraw %}, 這會引用 每一個數組元素的值來替代(Andrew 和 Bob 替換 name, 以及各自的問候信息.)

當返回到你的瀏覽器, 你還看不到任何的改變. 因為訊息數組還沒被傳送到模板, 所以Meteor遍歷不到任何東西來呈現.

你的chat.html最后應該是這樣的

<head> <title>chat</title></head><body> {{> entryfield}} {{> messages}}</body><template name="entryfield">  <input type="text" id="name" placeholder="Name" /> <input type="text" id="message" placeholder="Your Message" /></template><template name="messages">  <p>    {{#each messages}}      <strong>{{name}}</strong>- {{message}}<br/>    {{/each}}  </p></template>


Javascript

從現在開始, 我們處理的大部分代碼都是客戶端代碼, 所以, 除非特別說明, 以下的代碼都是在if (Meteor.is_client)代碼塊中.

在我們編寫展示訊息的代碼之前,讓我們先新建一個Collection. 從本質上講, 這是一組Models. 換句話說, 在這個chat應用的環境下, Messages collection保存著整個聊天記錄, 而每條訊息記錄是一個Model.

在if語句前, 添加如下代碼來初始化Collection:

Messages = new Meteor.Collection('messages');

因為我們希望這個Collection可以在客戶端和服務端被創建, 所以我們把它寫在了客戶端代碼塊之外.

由于Meteor為我們做了大部分的工作, 要展示聊天記錄是非常容易的. 只需要把下面的代碼添加進if語句里邊.

Template.messages.messages = function(){  return Messages.find({}, { sort: { time: -1 }});}

讓我們拆開來分析這段代碼:

Template.messages.messages = function(){ … }

第一部分Template表示我們正在修改一個模板的行為.

Template.messages.messages = function(){ … }

第二部分messages是模板的名字, 表示是在修改哪一個模板. 例如,如果我們想要對"entryfield"模板做些什么, 只需把代碼改成

Template.entryfields.variable = function(){ … } 

(在這里, 請別這么做)

Template.messages.messages = function(){ … }

第三部分的這個messages代表的是一個這個模板里的一個變量. 還記得我們的each循環遍歷messages嗎? 這就是那個mesaages.

當你打開瀏覽器時, 頁面還是沒有什么改變. 這是意料之中的事, 因為我們只抓取的訊息, 而沒有展示出來.

此時,你的chat.js應該是這樣的. 是否很驚訝就只需在服務器寫這么些代碼我們就能展示一個實時的聊天記錄應用.

Messages = new Meteor.Collection('messages');if (Meteor.is_client) { Template.messages.messages = function(){  return Messages.find({}, { sort: { time: -1 }}); }}


在console里添加Message


這部分的內容是可選的, 當然它有助于你調試程序. 你可以直接跳過往下學習建立form來響應鍵盤事件(key press).

如果你想要測試你的訊息顯示代碼, 你可以手動插入一條記錄到數據庫. 打開你的瀏覽器控制臺, 并輸入如下:

Messages.insert({ name: 'Andrew', message: 'Hello world!', time: 0 })

這將會在數據庫中新建一條記錄, 如果正確的操作了的話,那瀏覽器就會即刻更新這條訊息在頁面上.

消息表單

回到chat.js文件當中,我們會將供輸入的form和數據庫鏈接起來以接收用戶聊天數據的提交。在底部添加下面的代碼,不過注意要在if語句塊中。

 

Template.entryfield.events = { "keydown #message": function(event){  if(event.which == 13){   // Submit the form   var name = document.getElementById('name');   var message = document.getElementById('message');    if(name.value != '' && message.value != ''){    Messages.insert({     name: name.value,     message: message.value,     time: Date.now()    });     name.value = '';    message.value = '';   }  } }}

代碼有點多,讓我們再回顧一遍。你也許還記得,在Template后面的第二個單詞決定了我們正在修改的是哪個模板。不過跟之前不同的是,我們寫的代碼是用來綁定數據庫和messages模板的,我們正在修改的模板是entryfield。

這個模板中events的屬性包含了一個object,events的屬性按照下面的格式呈現:

 
"[eventname] [selector]"
例如,如果我們想為一個ID為hello的button綁定一個點擊事件的話,我們會把下面的代碼加入到events的個結構體當中。
 
"click #hello": function(event){ … }
在我們的例子當中,我們是將一個函數綁定到了ID為“message”的一個keydown事件當中。如果你還記得,這段代碼早在我們在chat.html文件中建立模板的時候就已經設定好了。


在事件對象中,每個key都有一個函數作為它的值。這個函數在事件被調用時執行,其中事件對象作為第一個參數傳遞給該函數。在我們的app里,每當ID帶有“message”的輸入欄中有任意鍵被按下(keydown)時,該函數就被調用了。

函數內的代碼相當簡單。首先,我們檢查回車鍵是否被按下(輸入中有13的關鍵代碼)。第二,我們通過ID取得兩個輸入欄的DOM元素。第三,我們檢查并確保輸入值不為空,以防止用戶提交一個空的名字或信息(name or message)。

注意下面的代碼很重要。這段代碼是將message插入數據庫。

Messages.insert({ name: name.value, message: message.value, time: Date.now()});

正如你看到的,這和我們插入到控制臺的代碼類似,但不是硬編碼的數值,我們用的是DOM元素的值。此外,我們加入了當前時間,以保證聊天日志被正確的按時間排序。


最后,我們將兩個輸入的值簡單的設為''以清空輸入欄。

現在,如果你進入瀏覽器,你可以試著輸入一個名字與信息到兩個輸入欄。按下回車以后,輸入欄將被清除,一個新的消息會出現在你的輸入字段的正下方。打開另一個瀏覽器窗口,導航到同一個URL(http://localhost:3000/)。試著鍵入另一個信息,而

正如你看到的,Meteor非常強大。不需要寫一行明確更新消息日志的代碼,新的信息顯示出來并同步到多個瀏覽器和客戶端。

總結

雖然Meteor工作起來非??幔乙灿幸恍┓浅S杏玫膽弥С炙?,比如Derby.js,但它是不成熟的。一個說明這一點例子就是,瀏覽文檔并找找紅色的引文。例如,關于MongoDB集合該文檔做了如下陳述:

    目前客戶端被給予集合的完全寫訪問權限。它們可以執行任意的更新命令。一旦我們建立鑒權認證,你將能夠限制客戶端的直接插入,更新和刪除。我們也在考慮校驗器或者其他類似ORM的功能。

任何用戶擁有完全的寫訪問權限是一個非常大的問題,因為對任何一個app產品――如果一個用戶對你的整個數據庫有寫訪問權限,這是一個相當大的安全問題。

看到Meteor(和Derby.js!)在像哪個方向前進是令人激動的,但是除非它成熟一點,它可能不是一個產品級應用的最好選擇。期待那1100萬美元資金能很好的利用起來。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久伊人日本| 国模精品视频一区二区三区| 久久久久一本一区二区青青蜜月| 欧美精品在线播放| 欧美日韩另类在线| 日韩视频亚洲视频| 欧美一级片久久久久久久| 欧美性生交大片免费| 日韩性生活视频| 国产精品永久免费视频| 国产亚洲成精品久久| 欧美成人在线免费| 激情亚洲一区二区三区四区| 国产精品久久久久久久久久久不卡| 精品综合久久久久久97| 九九精品在线视频| 久久国产精品久久久久久久久久| 亚洲视频在线观看| 国产精品专区h在线观看| 俺去了亚洲欧美日韩| 国产精品美乳一区二区免费| zzjj国产精品一区二区| 亚洲国产欧美在线成人app| 欧美一级大片在线观看| 亚洲精品xxxx| 中文字幕亚洲一区二区三区五十路| 亚洲人成伊人成综合网久久久| 性夜试看影院91社区| 国产精品久久久久久一区二区| 国产精品成人播放| 久久成人精品视频| 亚洲国产精久久久久久久| 精品国产依人香蕉在线精品| 少妇激情综合网| 久久伊人精品一区二区三区| 91九色精品视频| 国产精品自拍视频| 国产一区二区三区久久精品| 69久久夜色精品国产7777| 美女999久久久精品视频| 日本a级片电影一区二区| 日韩高清a**址| 亚洲娇小xxxx欧美娇小| 国产视频自拍一区| 久久久久久九九九| 成人在线小视频| 国产精品777| 久久五月情影视| 欧美成人小视频| 欧美午夜片在线免费观看| 午夜精品一区二区三区在线| 17婷婷久久www| 成人国内精品久久久久一区| 97色伦亚洲国产| 日本一区二区在线播放| 成人免费观看49www在线观看| 久久久久久久国产| 国产亚洲a∨片在线观看| 日本aⅴ大伊香蕉精品视频| 欧美一级成年大片在线观看| 97超级碰碰人国产在线观看| 欧美久久久精品| 国产精品中文字幕久久久| 日韩精品免费在线观看| 亚洲国产古装精品网站| 欧美最猛性xxxxx亚洲精品| 久久国产精品免费视频| 久久人人爽人人| 亚洲成年人在线播放| 国产小视频91| 欧美成人免费大片| 精品中文字幕在线| 欧美电影免费看| 亚洲午夜精品视频| 91av视频在线观看| 国产成人免费av电影| 精品视频在线播放色网色视频| 欧美日韩国产色| 中国日韩欧美久久久久久久久| 92国产精品视频| 亚洲嫩模很污视频| 91在线直播亚洲| 亚洲老司机av| 亚洲乱码国产乱码精品精| 国产精品夜色7777狼人| 欧美国产视频日韩| 欧美性受xxxx白人性爽| 欧美激情免费视频| 日韩精品中文字幕在线观看| 精品香蕉一区二区三区| 国产日韩欧美影视| 日韩在线免费观看视频| 亚洲成人动漫在线播放| 日韩电影中文字幕一区| 51ⅴ精品国产91久久久久久| 精品福利视频导航| 尤物精品国产第一福利三区| 欧美日韩亚洲精品一区二区三区| 秋霞成人午夜鲁丝一区二区三区| www国产精品视频| 国产精品www网站| 91精品久久久久久久久| 亚洲国产精品久久91精品| 亚洲xxx自由成熟| 国产精品久久久久久网站| 日韩精品免费在线视频观看| 欧美性受xxxx黑人猛交| 少妇高潮久久77777| 亚洲xxxxx电影| 日韩一区二区久久久| 中文字幕精品久久久久| 国产免费一区二区三区在线能观看| 日韩视频在线免费观看| 欧美精品videofree1080p| 亚洲va码欧洲m码| 精品久久香蕉国产线看观看gif| 福利视频导航一区| 欧美成人一区二区三区电影| 欧美裸体男粗大视频在线观看| 国产91精品高潮白浆喷水| 亚洲精品自产拍| 91丨九色丨国产在线| 亚洲全黄一级网站| 久久精品视频播放| 黑人欧美xxxx| 国产精品天天狠天天看| 国产精品看片资源| 亚洲一区二区久久| 色综久久综合桃花网| 九九九久久久久久| 国产精品美女av| 一区二区在线免费视频| 国产精品午夜视频| 富二代精品短视频| 日韩精品在线视频| 26uuu亚洲国产精品| 亚洲欧美在线磁力| 久久久免费在线观看| 国产欧美最新羞羞视频在线观看| 国产精品美腿一区在线看| 亚洲va欧美va国产综合久久| 亚洲精品第一国产综合精品| 久久天天躁狠狠躁夜夜躁| 一区二区在线视频| 国产盗摄xxxx视频xxx69| 日韩精品在线视频观看| 色播久久人人爽人人爽人人片视av| 欧美成人性色生活仑片| 久久人人爽人人爽人人片亚洲| 日韩免费观看高清| 日韩av在线看| 欧美在线观看网站| 欧美猛少妇色xxxxx| 一区二区欧美在线| 亚洲国产小视频在线观看| 国产精品一区二区女厕厕| 亚洲最大中文字幕| 日韩在线免费观看视频| 亚洲free性xxxx护士hd| 久久这里只有精品视频首页| 亚洲欧洲成视频免费观看| 久久中国妇女中文字幕| 亚洲国产另类久久精品| 国产欧美欧洲在线观看|