Статьи

Чат в реальном времени с модулями и Node.js

В этом руководстве я покажу вам, как реализовать приложение для чата в реальном времени с Node.js, Socket.IO и MongoDB, а затем мы вместе развернем это приложение в Modulus.

Прежде всего, позвольте мне показать вам окончательный вид приложения, которое у нас будет в конце статьи.

чат-экран

Node.js будет ядром приложения с Express в качестве MVC, MongoDB для базы данных и Socket.IO для связи в реальном времени. Когда мы закончим, мы развернем наше приложение в модуле. Часть MongoDB фактически существует внутри модуля.

  1. Джон хочет использовать наше приложение и открывает его в браузере.
  2. На первой странице он выбирает псевдоним, используемый в чате, и входит в чат.
  3. В текстовой области он что-то пишет и нажимает Enter.
  4. Текст отправляется в службу RESTful (Express), а этот текст записывается в MongoDB.
  5. Перед записью в MongoDB тот же текст будет транслироваться пользователям, которые в настоящее время вошли в приложение чата.

Как видите, это очень простое приложение, но оно охватывает практически все для веб-приложения. В этом приложении нет системы каналов, но вы можете развить исходный код и реализовать модуль канала для практики.

Сначала я попытаюсь объяснить небольшие части проекта и в конце объединить их. Я начну с задней части до передней части. Итак, начнем с доменных объектов (моделей MongoDB).

Для абстракции базы данных мы будем использовать Mongoose . В этом проекте у нас есть только одна модель под названием Message . Эта модель сообщения содержит только text , createDate ,   и author . Не существует модели для автора, такого как User , потому что мы не будем полностью внедрять систему регистрации / входа пользователя. Будет простая страница, предоставляющая псевдоним, и этот псевдоним будет сохранен в файле cookie. Это будет использоваться в модели Message как текст в поле author . Вы можете увидеть пример модели JSON ниже:

1
2
3
4
5
{
    text: «Hi, is there any Full Stack Developer here?»
    author: «john_the_full_stack»,
    createDate: «2015.05.15»
}

Чтобы создать подобные документы, вы можете реализовать модель, используя нижеприведенные функции Mongoose:

01
02
03
04
05
06
07
08
09
10
11
12
var mongoose = require(‘mongoose’)
 
var Message = new mongoose.Schema({
    author: String,
    message: String,
    createDate: {
        type: Date,
        default: Date.now
    }
});
 
mongoose.model(‘Message’, Message)

Просто импортируйте модуль Mongoose, определите вашу модель с ее полями и атрибутами полей в формате JSON и создайте модель с именем Message . Эта модель будет включена в страницы, которые вы хотите использовать.

Возможно, у вас есть вопрос о том, почему мы храним сообщение в базе данных, когда мы уже транслировали это сообщение пользователю на том же канале. Это правда, что вам не нужно хранить сообщения чата, но я просто хотел объяснить уровень интеграции базы данных. В любом случае, мы будем использовать эту модель в нашем проекте внутри контроллеров. Контроллеры?

Как я уже говорил ранее, мы будем использовать Express для MVC. И с   здесь выступает за Controller . Для наших проектов будет только две конечные точки для обмена сообщениями. Один из них предназначен для загрузки недавних сообщений чата, а второй — для обработки отправленных сообщений чата для сохранения в базе данных и последующей трансляции в канал.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
…..
app.get(‘/chat’, function(req, res){
    res.sendFile(__dirname + ‘/index.html’);
});
 
app.get(‘/login’, function(req, res){
    res.sendFile(__dirname + ‘/login.html’);
});
 
app.post(‘/messages’, function(req, res, next) {
    var message = req.body.message;
    var author = req.body.author;
    var messageModel = new Message();
    messageModel.author = author;
    messageModel.message = message;
    messageModel.save(function (err, result) {
       if (!err) {
           Message.find({}).sort(‘-createDate’).limit(5).exec(function(err, messages) {
               io.emit(«message», messages);
           });
           res.send(«Message Sent!»);
       } else {
           res.send(«Technical error occurred!»);
       }
    });
});
 
app.get(‘/messages’, function(req, res, next) {
    Message.find({}).sort(‘-createDate’).limit(5).exec(function(err, messages) {
        res.json(messages);
    });
});
…..

Первый и второй контроллеры предназначены только для обслуживания статических HTML-файлов для страниц чата и входа в систему. Третий — для обработки почтового запроса к /messages   конечная точка для создания новых сообщений. В этом контроллере, прежде всего, тело запроса преобразуется в модель сообщения, а затем эта модель сохраняется в базе данных с помощью функции save Mongoose.  

Я не буду слишком углубляться в Mongoose — вы можете посмотреть документацию для получения более подробной информации. Вы можете предоставить функцию обратного вызова для функции сохранения, чтобы проверить, есть ли какая-либо проблема или нет. Если это успешно, мы извлекли последние пять записей, отсортированных в порядке убывания по createDate , и передали пять сообщений клиентам в канале.

Хорошо, мы закончили MC .   Давайте перейдем к части View .

В общем, в Express можно использовать шаблонизатор, такой как Jade , EJS , Handlebars и т. Д. Тем не менее, у нас есть только одна страница, и это сообщение чата, поэтому я буду обслуживать это статически. На самом деле, как я сказал выше, есть еще два контроллера для обслуживания этой статической HTML-страницы. Вы можете увидеть следующее для показа статической HTML-страницы.

1
2
3
4
5
6
7
app.get(‘/chat’, function(req, res){
    res.sendFile(__dirname + ‘/index.html’);
});
 
app.get(‘/login’, function(req, res){
    res.sendFile(__dirname + ‘/login.html’);
});

Эта конечная точка просто обслуживает index.html и login.html с помощью res.sendFile . И то и другое   index.html и login.html находятся в той же папке, что и server.js, поэтому мы использовали __dirname перед именем файла HTML.

На первой странице я использовал Bootstrap, и нет необходимости объяснять, как мне это удалось. Я просто привязал функцию к текстовому полю, и всякий раз, когда вы нажимаете клавишу Enter или кнопку « Отправить» , сообщение будет отправляться на серверную службу.

На этой странице также есть необходимый js-файл Socket.IO для прослушивания канала под названием message . Модуль Socket.IO уже импортирован в бэкэнд, и когда вы используете этот модуль на стороне сервера, он автоматически добавляет конечную точку для обслуживания js-файла Socket.IO, но мы используем ту, которая подается из cdn <script src="//cdn.socket.io/socket.io-1.3.5.js"></script> . Всякий раз, когда новое сообщение поступает на этот канал, оно автоматически обнаруживается, и список сообщений обновляется последними пятью сообщениями.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<script>
       var socket = io();
       socket.on(«message», function (messages) {
           refreshMessages(messages);
       });
 
       function refreshMessages(messages) {
           $(«.media-list»).html(«»);
           $.each(messages.reverse(), function(i, message) {
               $(«.media-list»).append(‘<li class=»media»><div class=»media-body»><div class=»media»><div class=»media-body»>’
               + message.message + ‘<br/><small class=»text-muted»>’ + message.author + ‘ |
           });
       }
 
       $(function(){
 
           if (typeof $.cookie(«realtime-chat-nickname») === ‘undefined’) {
               window.location = «/login»
           } else {
               $.get(«/messages», function (messages) {
                   refreshMessages(messages)
               });
 
               $(«#sendMessage»).on(«click», function() {
                   sendMessage()
               });
 
               $(‘#messageText’).keyup(function(e){
                   if(e.keyCode == 13)
                   {
                       sendMessage();
                   }
               });
           }
 
           function sendMessage() {
               $container = $(‘.media-list’);
               $container[0].scrollTop = $container[0].scrollHeight;
               var message = $(«#messageText»).val();
               var author = $.cookie(«realtime-chat-nickname»);
               $.post( «/messages», {message: message, author: author}, function( data ) {
                   $(«#messageText»).val(«»)
               });
               $container.animate({ scrollTop: $container[0].scrollHeight }, «slow»);
           }
       })
   </script>

В приведенном выше коде есть еще одна проверка: часть cookie. Если вы не выбрали ни одного псевдонима для чата, это означает, что для псевдонима не настроен файл cookie, и вы будете автоматически перенаправлены на страницу входа.

Если нет, то последние пять сообщений будут получены простым Ajax-вызовом в конечную точку /messages . Таким же образом, всякий раз, когда вы нажимаете кнопку « Отправить» или нажимаете клавишу « Ввод» , текстовое сообщение будет извлечено из текстового поля, а псевдоним будет извлечен из файла cookie, и эти значения будут отправлены на сервер с сообщением. запрос. Здесь нет строгой проверки псевдонима, потому что я хотел сосредоточиться на части реального времени, а не на части аутентификации пользователя.

Как видите, общая структура проекта очень проста. Давайте перейдем к части развертывания. Как я уже говорил ранее, мы будем использовать Modulus , один из лучших PaaS для развертывания, масштабирования и мониторинга вашего приложения на выбранном вами языке.

Первое, что приходит мне в голову, это показать вам, как развернуть, но для успешного развертывания нам нужна рабочая база данных. Давайте посмотрим, как создать базу данных на модуле и затем выполнить развертывание.

Перейдите на панель инструментов Modulus после создания учетной записи. Щелкните меню « Базы данных» слева и выберите « Создать базу данных».

Щелкните меню «Базы данных» слева и выберите «Создать базу данных».

Заполните обязательные поля во всплывающей форме, как показано ниже.

Заполните обязательные поля во всплывающей форме CREATE DATABASE

Когда вы заполните обязательные поля и нажмете « Создать», он создаст для вас базу данных MongoDB, и вы увидите ее URL на экране. Мы будем использовать MONGO URI ,   так что скопируйте этот URI.

Ваша база данных была создана и готова к использованию

В нашем проекте Mongo URI выбирается из переменной среды MONGO_URI , и вам нужно установить эту переменную среды на панели мониторинга. Перейдите на панель инструментов, выберите меню « Проекты» , выберите свой проект в списке и нажмите « Администрирование» в левом меню. На этой странице вы увидите раздел переменных среды, когда прокрутите страницу вниз, как показано ниже.

MONGO_URI Value

Вы можете развернуть в модуле двумя способами:

  • загрузка файла ZIP проекта с помощью панели инструментов
  • Развертывание из командной строки с помощью Modulus CLI

Я продолжу с параметром командной строки, потому что другой легко сделать. Прежде всего, установите модуль CLI:

1
npm install -g modulus

Перейдите в папку вашего проекта и выполните следующую команду, чтобы войти в модуль.

1
modulus login

Когда вы выполните вышеуказанную команду, вам будет предложено ввести имя пользователя и пароль:

предложить ввести имя пользователя и пароль

Если вы создали учетную запись с помощью GitHub, вы можете использовать опцию --github .

1
modulus login —github

Теперь вы вошли в модуль, и пришло время создать проект. Используйте следующую команду для создания проекта:

1
modulus project create «Realtime Chat»

Когда вы запустите эту функцию, у вас спросят время выполнения. Выберите первую опцию, которая называется Node.js, а во-вторых, вас спросят о размере сервопривода, и вы можете оставить его по умолчанию.

Сохранить размер сервопривода по умолчанию

Мы создали проект, и на этот раз мы развернем наш текущий проект в модуле. Выполните следующую команду, чтобы отправить текущий проект в проект чата в реальном времени на стороне модуля.

1
modulus deploy

Он развернет ваш проект, и вы получите URL запущенного проекта в конце сообщения об успешном развертывании:

1
Realtime Chat running at realtime-chat-46792.onmodulus.net

Как видите, развертывание в модуле очень просто!

Модуль CLI имеет очень полезные команды для использования во время развертывания проекта или во время выполнения. Например, для привязки журналов вашего работающего проекта вы можете использовать modulus project logs tail , для создания базы данных MongoDB используйте modulus mongo create <db-name> базы-данных modulus mongo create <db-name> , чтобы задать переменную среды, используйте modulus env set <key> <value> и т. д. Вы можете увидеть полный список команд с помощью справки Modulus.

Основная цель этого руководства состояла в том, чтобы показать вам, как создать приложение для чата в реальном времени с Node.js, Socket.IO и MongoDB. Для запуска проекта в производстве в качестве поставщика PaaS используется модуль Modulus. Модуль имеет очень простые шаги для развертывания, а также имеет внутреннюю базу данных (MongoDB) для наших проектов. Помимо этого, вы можете использовать очень полезные инструменты на панели инструментов Modulus, такие как журналы, уведомления, автоматическое масштабирование, администрирование базы данных и так далее.

Чтобы подписаться на модуль, нажмите здесь и получите дополнительные 10 долларов исключительно за то, что читаете Tuts +. Используйте промо-код ModulusChat10 .

Для получения дополнительной информации о корпоративном предложении Modulus нажмите здесь .