MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Trò chuyện thời gian thực với Modulus và Node.js

Trong hướng dẫn này, tôi sẽ chỉ cho bạn cách triển khai ứng dụng trò chuyện thời gian thực với Node.js, Socket.IO và MongoDB, sau đó chúng ta sẽ cùng nhau triển khai ứng dụng này cho Modulus.

Trước hết, hãy để tôi cho bạn thấy cái nhìn cuối cùng của ứng dụng mà chúng ta sẽ có ở cuối bài viết.

Node.js sẽ là hạt nhân của ứng dụng, với Express là MVC, MongoDB cho cơ sở dữ liệu và Socket.IO cho giao tiếp thời gian thực. Khi chúng tôi hoàn thành, chúng tôi sẽ triển khai ứng dụng của mình cho Modulus. Phần MongoDB thực sự tồn tại bên trong Modulus.

1. Tình huống

  1. John muốn sử dụng ứng dụng của chúng tôi và mở nó trong trình duyệt.
  2. Trên trang đầu tiên, anh ấy chọn cách sử dụng biệt hiệu trong khi trò chuyện và đăng nhập để trò chuyện.
  3. Trong vùng văn bản, anh ấy viết gì đó và nhấn Enter.
  4. Văn bản được gửi tới dịch vụ RESTful (Express) và văn bản này được viết tới MongoDB.
  5. Trước khi viết bằng MongoDB, văn bản tương tự sẽ được phát tới những người dùng hiện đang đăng nhập vào ứng dụng trò chuyện.

Như bạn có thể thấy, đây là một ứng dụng rất đơn giản, nhưng nó bao gồm hầu hết mọi thứ cho một ứng dụng web. Không có hệ thống kênh trong ứng dụng này, nhưng bạn có thể phân nhánh mã nguồn và triển khai mô-đun kênh để thực hành.

2. Thiết kế dự án từ Scratch

Tôi sẽ cố gắng giải thích những phần nhỏ của dự án trước và kết hợp chúng lại ở phần cuối. Tôi sẽ bắt đầu từ back end đến front end. Vì vậy, hãy bắt đầu với các đối tượng miền (mô hình MongoDB).

2.1. Mô hình

Để trừu tượng hóa cơ sở dữ liệu, chúng tôi sẽ sử dụng Mongoose. Trong dự án này, chúng tôi chỉ có một mô hình được gọi là Message . Mẫu tin nhắn này chỉ chứa text , createDate , author . Không có mô hình nào cho tác giả như User , bởi vì chúng tôi sẽ không triển khai đầy đủ hệ thống đăng ký / đăng nhập người dùng. Sẽ có một trang cung cấp biệt hiệu đơn giản và biệt hiệu này sẽ được lưu vào cookie. Điều này sẽ được sử dụng trong Message mô hình dưới dạng văn bản trong author đồng ruộng. Bạn có thể xem một mô hình JSON mẫu bên dưới:

{

    text: "Hi, is there any Full Stack Developer here?"

    author: "john_the_full_stack",

    createDate: "2015.05.15"

}

Để tạo các tài liệu như thế này, bạn có thể triển khai một mô hình bằng cách sử dụng các hàm Mongoose bên dưới:

var mongoose = require('mongoose')



var Message = new mongoose.Schema({

    author: String,

    message: String,

    createDate: {

        type: Date,

        default: Date.now

    }

});



mongoose.model('Message', Message)

Chỉ cần nhập mô-đun Mongoose, xác định mô hình của bạn với các trường và thuộc tính trường của nó ở định dạng JSON và tạo mô hình với tên Message . Mô hình này sẽ được đưa vào các trang mà bạn muốn sử dụng.

Có thể bạn có câu hỏi về lý do tại sao chúng tôi lưu trữ thông báo trong cơ sở dữ liệu, khi chúng tôi đã phát thông báo này đến người dùng trong cùng một kênh. Đúng là bạn không cần phải lưu trữ các tin nhắn trò chuyện, nhưng tôi chỉ muốn giải thích về lớp tích hợp cơ sở dữ liệu. Dù sao, chúng tôi sẽ sử dụng mô hình này trong dự án của chúng tôi bên trong bộ điều khiển. Bộ điều khiển?

2.2. Bộ điều khiển

Như tôi đã nói trước đó, chúng tôi sẽ sử dụng Express cho phần MVC. Và C ở đây là viết tắt của Controller . Đối với các dự án của chúng tôi, sẽ chỉ có hai điểm cuối để nhắn tin. Một trong số chúng là để tải các tin nhắn trò chuyện gần đây và cái thứ hai là để xử lý các tin nhắn trò chuyện đã gửi để lưu trữ trong cơ sở dữ liệu, sau đó phát vào kênh.

.....

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);

    });

});

.....

Bộ điều khiển thứ nhất và thứ hai chỉ để phục vụ các tệp HTML tĩnh cho các trang đăng nhập và trò chuyện. Cái thứ ba là để xử lý yêu cầu gửi đến /messages điểm cuối để tạo tin nhắn mới. Trong bộ điều khiển này, trước hết phần thân yêu cầu được chuyển đổi thành mô hình Message, và sau đó mô hình này được lưu vào cơ sở dữ liệu bằng cách sử dụng hàm Mongoose save .

Tôi sẽ không đi sâu vào Mongoose nhiều — bạn có thể xem tài liệu để biết thêm chi tiết. Bạn có thể cung cấp chức năng gọi lại cho chức năng lưu để kiểm tra xem có vấn đề gì hay không. Nếu thành công, chúng tôi đã tìm nạp năm bản ghi cuối cùng được sắp xếp theo thứ tự giảm dần theo createDate và đã phát năm tin nhắn cho các khách hàng trong kênh.

Được rồi, chúng ta đã hoàn thành MC . Hãy chuyển sang View một phần.

2.3. Xem

Nói chung, một công cụ mẫu như Jade, EJS, Handlebars, v.v., có thể được sử dụng trong Express. Tuy nhiên, chúng tôi chỉ có một trang và đó là tin nhắn trò chuyện, vì vậy tôi sẽ phục vụ trang này một cách tĩnh. Trên thực tế, như tôi đã nói ở trên, có hai bộ điều khiển khác để phục vụ trang HTML tĩnh này. Bạn có thể thấy phần sau để phân phát một trang HTML tĩnh.

app.get('/chat', function(req, res){

    res.sendFile(__dirname + '/index.html');

});



app.get('/login', function(req, res){

    res.sendFile(__dirname + '/login.html');

});

Điểm cuối này chỉ phục vụ index.html và login.html bằng cách sử dụng res.sendFile . Cả index.html và login.html nằm trong cùng một thư mục với server.js, đó là lý do tại sao chúng tôi sử dụng __dirname trước tên tệp HTML.

2.4. Giao diện người dùng

Trong trang front-end, tôi đã sử dụng Bootstrap và không cần phải giải thích cách tôi quản lý để làm điều đó. Đơn giản, tôi đã liên kết một hàm vào một hộp văn bản và bất cứ khi nào bạn nhấn Enter phím hoặc Gửi , tin nhắn sẽ được gửi đến dịch vụ đầu cuối.

Trang này cũng có tệp js cần thiết của Socket.IO để nghe kênh có tên message . Mô-đun Socket.IO đã được nhập ở phần cuối và khi bạn sử dụng mô-đun này ở phía máy chủ, nó sẽ tự động thêm một điểm cuối để phân phát tệp Socket.IO js, nhưng chúng tôi sử dụng một điểm cuối được cung cấp từ cdn <script src="//cdn.socket.io/socket.io-1.3.5.js"></script> . Bất cứ khi nào có tin nhắn mới đến kênh này, nó sẽ tự động được phát hiện và danh sách tin nhắn sẽ được làm mới với năm tin nhắn cuối cùng.

<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 + ' | ' + message.createDate + '</small><hr/></div></div></div></li>');

            });

        }



        $(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>

Có một kiểm tra nữa trong đoạn mã trên:phần cookie. Nếu bạn chưa chọn bất kỳ biệt hiệu nào để trò chuyện, điều đó có nghĩa là cookie không được đặt cho biệt hiệu và bạn sẽ tự động được chuyển hướng đến trang đăng nhập.

Nếu không, năm thông báo cuối cùng sẽ được tìm nạp bằng một lệnh gọi Ajax đơn giản tới /messages điểm cuối. Theo cách tương tự, bất cứ khi nào bạn nhấp vào nút Gửi hoặc nhấn nút Enter khóa, tin nhắn văn bản sẽ được tìm nạp từ hộp văn bản và biệt hiệu sẽ được tìm nạp từ cookie và những giá trị đó sẽ được gửi đến máy chủ cùng với một yêu cầu đăng. Không có kiểm tra chặt chẽ cho biệt hiệu ở đây, vì tôi muốn tập trung vào phần thời gian thực, không phải phần xác thực người dùng.

Như bạn có thể thấy, cấu trúc tổng thể của dự án rất đơn giản. Chúng ta cùng đến với phần triển khai. Như tôi đã nói trước đó, chúng tôi sẽ sử dụng Modulus, một trong những PaaS tốt nhất để triển khai, mở rộng và giám sát ứng dụng của bạn bằng ngôn ngữ bạn chọn.

3. Triển khai

3.1. Điều kiện tiên quyết

Điều đầu tiên tôi nghĩ đến là chỉ cho bạn cách triển khai, nhưng để triển khai thành công, chúng ta cần một cơ sở dữ liệu hoạt động. Chúng ta hãy xem cách tạo cơ sở dữ liệu trên Modulus và sau đó thực hiện triển khai.

Chuyển đến bảng điều khiển Modulus sau khi tạo tài khoản. Nhấp vào Cơ sở dữ liệu ở bên trái và nhấp vào Tạo cơ sở dữ liệu.

Điền vào các trường bắt buộc trong biểu mẫu bật lên như bên dưới.

Khi bạn điền vào các trường bắt buộc và nhấp vào Tạo, nó sẽ tạo cơ sở dữ liệu MongoDB cho bạn và bạn sẽ thấy URL cơ sở dữ liệu của mình trên màn hình. Chúng tôi sẽ sử dụng MONGO URI , vì vậy hãy sao chép URI đó.

Trong dự án của chúng tôi, Mongo URI được tìm nạp từ biến môi trường MONGO_URI và bạn cần đặt biến môi trường đó trong trang tổng quan. Đi tới trang tổng quan, nhấp vào Dự án trình đơn, chọn dự án của bạn trong danh sách và nhấp vào Quản trị trong menu bên trái. Trong trang này, bạn sẽ thấy phần biến môi trường khi cuộn xuống trang, như hình bên dưới.

Bạn có thể triển khai tới Modulus theo hai cách:

  • tải lên tệp ZIP của dự án bằng cách sử dụng trang tổng quan
  • triển khai từ dòng lệnh bằng cách sử dụng Modulus CLI

Tôi sẽ tiếp tục với tùy chọn dòng lệnh, vì tùy chọn còn lại rất dễ thực hiện. Trước hết, hãy cài đặt Modulus CLI:

npm install -g modulus

Đi tới thư mục dự án của bạn và thực hiện lệnh sau để đăng nhập vào Modulus.

modulus login

Khi bạn thực hiện lệnh trên, bạn sẽ được nhắc nhập tên người dùng và mật khẩu:

Nếu bạn đã tạo tài khoản bằng GitHub, bạn có thể sử dụng --github tùy chọn.

modulus login --github

Bây giờ bạn đã đăng nhập vào Modulus và đã đến lúc tạo một dự án. Sử dụng lệnh sau để tạo một dự án:

modulus project create "Realtime Chat"

Khi bạn chạy chức năng này, bạn sẽ được yêu cầu về thời gian chạy. Chọn tùy chọn đầu tiên, là Node.js, và tùy chọn thứ hai, bạn sẽ được hỏi về kích thước servo và bạn có thể giữ nó làm mặc định.

Chúng tôi đã tạo một dự án và lần này chúng tôi sẽ triển khai dự án hiện tại của mình lên Modulus. Thực thi lệnh sau để gửi dự án hiện tại tới Trò chuyện thời gian thực dự án về phía Mô-đun.

modulus deploy

Nó sẽ triển khai dự án của bạn và bạn sẽ nhận được URL dự án đang chạy của mình ở cuối thông báo triển khai thành công:

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

Như bạn có thể thấy, việc triển khai Modulus rất dễ dàng!

Modulus CLI có các lệnh rất hữu ích để sử dụng trong quá trình triển khai dự án của bạn hoặc trong thời gian chạy. Ví dụ:để chỉnh sửa nhật ký cho dự án đang chạy của bạn, bạn có thể sử dụng modulus project logs tail , để tạo cơ sở dữ liệu MongoDB, hãy sử dụng modulus mongo create <db-name> , để đặt một biến môi trường, hãy sử dụng modulus env set <key> <value> , v.v. Bạn có thể xem danh sách đầy đủ các lệnh bằng cách sử dụng trợ giúp của Modulus.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Cách tạo chỉ mục trong MongoDB qua .NET

  2. MongoDB PHP UTF-8 sự cố

  3. tạo và cập nhật nhiều tài liệu MongoDB trong một lần gọi

  4. ghi lại tất cả các truy vấn mongoose kích hoạt trong ứng dụng

  5. Phương thức Mongoose 'static' so với phương thức 'instance'