>웹 프론트엔드 >JS 튜토리얼 >Meteor와 Node.js를 사용하여 실시간 채팅을 작성하는 예 application_node.js

Meteor와 Node.js를 사용하여 실시간 채팅을 작성하는 예 application_node.js

WBOY
WBOY원래의
2016-05-16 15:53:231272검색

Derby.js에 비해 자주 보는 프레임워크는 Meteor.js입니다. Derby와 유사하게 여러 클라이언트에서 실시간으로 뷰를 업데이트할 수도 있지만 위의 방법은 약간 다를 수 있습니다. Derby에서는 다양한 데이터베이스를 쉽게 사용할 수 있지만 Meteor는 MongoDB에만 가깝습니다. 실제로 Mongoose와 같은 클라이언트를 통해 데이터베이스에 접근하는 API는 MongoDB에서 사용하는 것과 동일합니다. 서버입니다. 제가 예상한 것과 매우 가깝습니다.

Meteor는 현재 몇 가지 단점과 논란이 있는 프레임워크이지만 실시간 요구 사항이 있는 애플리케이션을 구축하는 데는 매우 흥미로운 선택인 것 같습니다. 개인적으로 저는 여전히 전통적인 콜백을 기반으로 하는 프로그래밍 형식이 더 매력적입니다. 그러나 Derby에는 강력한 문서와 대규모 개발자 커뮤니티가 부족하여 의심할 여지 없이 큰 타격을 입게 됩니다. 어쩌면 시간이 지나면 바뀔 수도 있지만 Meteor가 최근에 1,100만 달러를 받았기 때문에 여전히 Meteor보다 훨씬 느릴 것입니다. 이 재정 지원은 Meteor의 존재와 지속적인 지원을 보장합니다. 재정적으로나 개발적으로 안정적인 프레임워크가 필요한 개발자에게 이 자금 지원은 Meteor를 더욱 향상시킬 것입니다. 새롭고 현실적이면서도 간단한 Meteor 애플리케이션을 만드는 방법은 기본적으로 Tom의 Vimeo 스크린캐스트 초보자 가이드를 기반으로 합니다. Tom의 Vimeo 스크린캐스트와의 가장 큰 차이점은 복사하여 붙여넣는 대신 이벤트를 처리하는 방식입니다. Meteor 예제의 코드를 사용하여 Enter 키를 사용하여 메시지를 제출하는 방법을 단계별로 살펴보겠습니다.

Meteor 애플리케이션 만들기

Derby와 Meteor의 공통점은 각각의 명령줄 도구입니다. Node에 내장된 npm 도구를 사용하는 Derby와 달리 Meteor는 자체 명령줄 도구를 사용합니다.

터미널(Mac OS X 및 Linux)에서 다음 명령을 실행하세요. (이 작업을 수행하기 전에 Node가 설치되어 있는지 확인하세요.)

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

Metror가 이 작업을 자체적으로 수행하고 명령줄 도구를 설치합니다.

새 프로젝트를 생성하려면 먼저 작업 디렉터리로 이동하여 아래 코드를 실행하세요. 이렇게 하면 Meteor와 기본 템플릿 프로그램이 포함된 디렉터리가 생성됩니다.

$meteor create chat

이제 해당 디렉토리로 이동하여 아래 코드를 실행하여 실행할 수 있습니다

$cdchat$meteor
Running on: http://localhost:3000/

가장 기본적인 애플리케이션을 보려면 최신 브라우저에서 http://localhost:3000/

만 열면 됩니다.

원하는 경우 Meteor에 내장된 meteor 배포 명령을 사용하여 Meteor 자체 서버에 애플리케이션을 배포할 수 있습니다.

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

코드를 업데이트하고 저장하면 연결된 모든 브라우저가 페이지를 실시간으로 업데이트합니다.

채팅 애플리케이션 개발

Meteor Create 명령으로 생성된 폴더에는 다양한 파일을 볼 수 있습니다. 숨겨진 파일을 보는 방법을 알고 있다면 .meteor 폴더도 볼 수 있습니다. 이 폴더에는 Meteor 자체와 MongoDB 데이터 파일이 포함되어 있습니다.

앱의 루트 폴더에서 chat.html, chat.css 및 chat.js의 세 가지 파일을 볼 수 있습니다. 이 세 가지 파일은 모두 고유한 설명과 함께 제공됩니다. HTML 파일에는 chat.css에 정의된 앱의 모델과 모양이 포함되어 있습니다. Javascript 파일에는 클라이언트 측과 서버 측에서 실행될 스크립트가 포함되어 있습니다. 구성 매개변수 및 비밀번호와 같은 어떤 것도 이 스크립트 파일에 입력하지 않는 것이 중요합니다. 애플리케이션 코드를 보면 누구든지 이러한 내용을 볼 수 있기 때문입니다.

좋아하는 텍스트 편집 소프트웨어로 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의 두 부분에 주목하세요. 이 블록의 코드는 별도로 실행됩니다. 이 코드를 실행하는 시스템이 클라이언트인 경우 clint 블록의 코드만 실행됩니다. 이는 실제 응용 프로그램에서 Meteor의 코드 공유 기능을 보여줍니다.

if의 Meteor.is_client 및 Meteor.is_server 섹션에서 모든 코드를 삭제하고 섹션 하나만 남겨 둡니다.

if (Meteor.is_client) { }

스크립트 파일을 저장하면 브라우저가 즉시 새 코드를 로드하기 위해 새로 고쳐집니다.

뷰 만들기

이 스크립트 파일 작업을 공식적으로 시작하기 전에 채팅 기록을 표시할 새 보기를 만들어야 합니다. 편집기에서 chat.html을 열고 hello라는 템플릿 태그를 포함하세요. 다음 부분

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

<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最后应该是这样的


 chat



 {{> entryfield}}

 {{> messages}}


<template name="entryfield">
  <input type="text" id="name" placeholder="Name" /> <input type="text" id="message" placeholder="Your Message" />
</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工作起来非常酷,而且也有一些非常有用的应用支持它,比如Derby.js,但它是不成熟的。一个说明这一点例子就是,浏览文档并找找红色的引文。例如,关于MongoDB集合该文档做了如下陈述:

    目前客户端被给予集合的完全写访问权限。它们可以执行任意的更新命令。一旦我们建立鉴权认证,你将能够限制客户端的直接插入,更新和删除。我们也在考虑校验器或者其他类似ORM的功能。

任何用户拥有完全的写访问权限是一个非常大的问题,因为对任何一个app产品——如果一个用户对你的整个数据库有写访问权限,这是一个相当大的安全问题。

看到Meteor(和Derby.js!)在像哪个方向前进是令人激动的,但是除非它成熟一点,它可能不是一个产品级应用的最好选择。期待那1100万美元资金能很好的利用起来。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.