Home >Web Front-end >JS Tutorial >Example of using Meteor and Node.js to write a real-time chat application_node.js
The framework I often see compared to Derby.js is Meteor.js. Similar to Derby, it can also update views in real time under multiple clients, although the method The above may be a little different from Derby. Derby can easily use a variety of databases, while Meteor is only close to MongoDB. In fact, the API for accessing the database through the client such as Mongoose is the same as what you use on the server. It’s very close to what I expected.
Although Meteor is now a framework with some shortcomings and controversies, Meteor seems to be a very interesting choice for building applications with real-time requirements. Personally, I still like Derby. The programming form based on traditional callbacks is more attractive to me, but in Derby Behind its power, it lacks robust documentation and a large developer community, which is undoubtedly a big blow. Maybe this will change over time, but it will still be much slower than Meteor, because The latter recently received $11 million in funding. This financial funding ensures Meteor's existence and continued support. For developers who need a financially and developmentally stable framework, this funding will only make Meteor even better. . 95712e0b0bc62c64b1fddfac486f9cb8 Today, let’s take a look at how to create a new, realistic yet simple Meteor application. Essentially, it’s one based on Tom’s Vimeo screencast Beginner's Guide. The biggest difference from Tom's Vimeo screencast is the way events are handled. Instead of copy-pasting code from a Meteor example, I'm going to go step-by-step through my own way of submitting a message using the Enter key. Let's get started. Right.
Create a Meteor application
A big plus point that Derby and Meteor have in common is their respective command line tools. Unlike Derby which uses Node’s built-in npm tool, Meteor uses its own.
In the terminal (Mac OS X and Linux), execute the following command. (Please make sure you have installed Node before doing this)
$curl https://install.meteor.com | /bin/sh
Metror will do it by itself and install the command line tools.
To create a new project, first go to your working directory and run the code below. This will create a directory that contains Meteor and a basic template program.
$meteor create chat
Now, you can go to that directory and run the code below to get it running
$cdchat$meteor Running on: http://localhost:3000/
To see this most basic application, you only need to open http://localhost:3000/
in any modern browserAs long as you want, you can use Meteor’s built-in meteor deploy command to deploy your application to Meteor’s own server
$meteor deploy my-app-name.meteor.com
As long as you update and save your code, all connected browsers will update their pages in real time.
Developing chat applications
In the folder generated by the Meteor Create command, you can see different files. If you know how to view hidden files, you can also see the .meteor folder. This folder contains Meteor itself, as well as MongoDB data files.
In the root folder of your App, you should be able to see these three files: chat.html, chat.css and chat.js. These three files all come with their own descriptions. The HTML file contains the App's model and appearance, which are defined by chat.css. Javascript files contain scripts to be executed on the client and server sides. It is important not to put anything into this script file, such as configuration parameters and passwords, as anyone can see these by looking at your application's code.
Open the chat.js file with your favorite text editing software. Personally, I like to use Sublime Text2 because this tool is simple and has multiple mouse status prompts.
You can see the following code in the chat.js file:
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 }); }
In Meteor.js, pay attention to the two parts of Meteor.is_client and Meteor.is_server in the if paragraph. The code in these blocks will be executed separately. When the machine running this code is the client, only the code in the clint block will be run. The same is true for the server. This illustrates Meteor's code sharing capabilities in practical applications.
Delete all the code in the Meteor.is_client and Meteor.is_server sections in the if, leaving only one section:
if (Meteor.is_client) { }
Note that after you save the script file, your browser will immediately refresh to load this new code.
Create View
Before we officially start working on this script file, we need to create a new view to display chat records. Open chat.html in the editor and delete the code in the body tag. Include the template tag named hello. Only Leave the following part
<head> <title>chat</title> </head> <body> </body>
Then add the following sentence in the body tag
{{> 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最后应该是这样的
chat {{> entryfield}} {{> messages}} <template name="entryfield"> <input type="text" id="name" placeholder="Name" /> <input type="text" id="message" placeholder="Your Message" /> </template>{{#each messages}} {{name}}- {{message}}
{{/each}}
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工作起来非常酷,而且也有一些非常有用的应用支持它,比如Derby.js,但它是不成熟的。一个说明这一点例子就是,浏览文档并找找红色的引文。例如,关于MongoDB集合该文档做了如下陈述:
目前客户端被给予集合的完全写访问权限。它们可以执行任意的更新命令。一旦我们建立鉴权认证,你将能够限制客户端的直接插入,更新和删除。我们也在考虑校验器或者其他类似ORM的功能。
任何用户拥有完全的写访问权限是一个非常大的问题,因为对任何一个app产品——如果一个用户对你的整个数据库有写访问权限,这是一个相当大的安全问题。
看到Meteor(和Derby.js!)在像哪个方向前进是令人激动的,但是除非它成熟一点,它可能不是一个产品级应用的最好选择。期待那1100万美元资金能很好的利用起来。