Express、Mongoose、Socket.ioを使用してNode.jsでリアルタイムチャットアプリケーションを構築する方法

このチュートリアルでは、Node.jsプラットフォームを使用して、ページを更新せずにメッセージを受信者に即座に送信および表示するリアルタイムチャットアプリケーションを構築します。これを実現するために、JavaScriptフレームワークExpress.jsとライブラリMongooseおよびSocket.ioを使用します。

始める前に、Node.jsの基本を簡単に見てみましょう。

Node.js

Node.jsは、ブラウザーの外部でJavaScriptコードを実行するオープンソースのクロスプラットフォームJavaScriptランタイム環境です。Nodeを使用することの最も重要な利点は、JavaScriptをフロントエンド言語とバックエンド言語の両方として使用できることです。

ご存知のとおり、JavaScriptは主にクライアント側のスクリプトに使用されていました。このスクリプトでは、スクリプトがWebページのHTMLに埋め込まれ、ユーザーのWebブラウザーのJavaScriptエンジンによってクライアント側で実行されます。

Node.jsを使用すると、開発者はJavaScriptを使用してコマンドラインツールを記述したり、サーバーサイドスクリプトを実行したりできます。サーバーサイドでスクリプトを実行して、ページがユーザーのWebブラウザーに送信される前に動的なWebページコンテンツを生成します。

ノードをインストールするには:

//nodejs.org/en/download/

ノードはシングルスレッドですが、非同期関数を使用する方が高速です。たとえば、Nodeは、ファイルがディスクから読み取られている間、またはHTTP要求が完了するのを待っている間に他のものを処理できます。非同期動作は、コールバックを使用して実装できます。また、JavaScriptはJSONおよびNo-SQLデータベースでうまく機能します。

NPMモジュール

Nodejsを使用すると、ライブラリのモジュールをアプリケーションに含めることができます。これらのモジュールは、ユーザー定義モジュールまたはサードパーティモジュールにすることができます。

サードパーティのモジュールは、次のコマンドを使用してインストールできます。

npm install module_name

インストールされたモジュールは、require()関数を使用して使用できます。

var module = require(‘module_name’)

Nodeアプリでは、package.jsonファイルを使用してモジュールのバージョンを維持します。このファイルは、次のコマンドで作成できます。

npm init

パッケージは次のようにインストールする必要があります。

npm install -s module_name

Nodeアプリケーションにモジュールとして追加できるフレームワークはたくさんあります。これらについては、必要に応じてさらに説明します。

シンプルなチャットアプリケーション

アプリでは、複数のユーザーが一緒にチャットできるようにする必要があります。メッセージは、ページを更新せずに更新する必要があります。簡単にするために、認証部分は避けます。

新しいプロジェクトディレクトリを作成してそこに移動することから始めることができます。次に、次のコマンドでプロジェクトを開始できます。

npm init

これにより、プロジェクトの詳細を入力するように求められます。

この後、package.jsonファイルが作成されます。

{ “name”: “test”, “version”: “1.0.0”, “description”: “”, “main”: “index.js”, “scripts”: { “test”: “echo \”Error: no test specified\” && exit 1" }, “author”: “”, “license”: “ISC” }

これでアプリディレクトリが設定されました。

最初に作成する必要があるのはサーバーです。それを作成するために、Expressという名前のフレームワークを利用します

Express.js

Express.js、または単にExpressは、Node.jsのWebアプリケーションフレームワークです。Expressは、Webおよびモバイルアプリケーション向けの堅牢な機能セットを提供します。Expressは、Node.jsの機能を曖昧にすることなく、基本的なWebアプリケーション機能の薄層を提供します。

次のコマンドを使用してExpress.jsをインストールします。

npm install -s express

package.jsonファイル内に、新しい行が追加されます。

dependencies”: { “express”: “⁴.16.3” }

次に、server.jsファイルを作成します。

このファイルでは、Expressを要求し、Expressのインスタンスから変数への参照を作成する必要があります。HTML、CSS、JavaScriptなどの静的コンテンツは、express.jsを使用して提供できます。

var express = require(‘express’); var app = express();

コードを使用してポートのリッスンを開始できます。

var server = app.listen(3000, () => { console.log(‘server is running on port’, server.address().port); });

次に、UIを表示するHTMLファイルindex.htmlを作成する必要があります。ブートストラップとJQuerycdnを追加しました。

//index.html    

Send Message

Send

空の< ; / script>タグは、クライアント側のJavaScriptコードを記述する場所になることに注意してください。

Expressにそのことを伝えるために、静的ファイルを使用します。server.js内に新しい行を追加します。

app.use(express.static(__dirname));

コマンドを使用してserver.jsを実行できます

node ./server.js

or a package called nodemon, so that the changes made in the code will be automatically detected. We will download nodemon using the command

npm install -g nodemon

-g — global, so that it is accessible in all projects.

We will run the code using the command

nodemon ./server.js

If you go to localhost:3000 we can see the index file:

Now that our server is up and running, we need to create our database. For this app we will having a No-SQL database and will be using Mongodb. I am setting up my mongodb in mlab.com. Our database will contain a single collection called messages with fields name and message.

In-order to connect this database to the app, we will use another package called Mongoose.

Mongoose

Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment. Mongoose can be installed using the command

npm install -s mongoose

Inside server.js we will require mongoose:

var mongoose = require(‘mongoose’);

And we will assign a variable, the URL of our mlab database:

var dbUrl = ‘mongodb://username:[email protected]:57981/simple-chat’

Mongoose will connect to the mlab database with the connect method:

mongoose.connect(dbUrl , (err) => { console.log(‘mongodb connected’,err); })

And we will be defining our message model as

var Message = mongoose.model(‘Message’,{ name : String, message : String})

We can implement the chat logic now. But before that there is one more package that needs to be added.

Body-Parser

Body-Parser extracts the entire body portion of an incoming request stream and exposes it on req.body. The middleware was a part of Express.js earlier, but now you have to install it separately.

Install it using the following command:

npm install -s body-parser

Add the following codes to server.js:

var bodyParser = require(‘body-parser’) app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false}))

Routing

Routing refers to how an application’s endpoints (URIs) respond to client requests. You define routing using methods of the Express app object that correspond to HTTP methods: app.get() to handle GET requests and app.post() to handle POST requests.

These routing methods specify a callback function (sometimes called “handler functions”) called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application “listens” for requests that match the specified routes and methods, and when it detects a match, it calls the specified callback function.

Now we need to create two routes to the messages for our chat to work.

Inside server.js:

get : will get all the message from database

app.get('/messages', (req, res) => { Message.find({},(err, messages)=> { res.send(messages); }) })

post : will post new messages created by the user to the database

app.post('/messages', (req, res) => { var message = new Message(req.body); message.save((err) =>{ if(err) sendStatus(500); res.sendStatus(200); }) })

In order to connect these routes to the front end we need to add the following code in the client side script tag in the index.html:

$(() => { $("#send").click(()=>{ sendMessage({ name: $("#name").val(), message:$("#message").val()}); }) getMessages() }) function addMessages(message){ $(“#messages”).append(` 

${message.name}

${message.message}

`) } function getMessages(){ $.get(‘//localhost:3000/messages', (data) => { data.forEach(addMessages); }) } function sendMessage(message){ $.post(‘//localhost:3000/messages', message) }

Here the sendMessage is used to invoke the post route of the messages, and save a message sent by the user. The message is created when a user clicks the send button.

Similarly the getMessage is used to invoke the get route of messages. This will get all the messages saved in the database and will be appended to the messages div.

The only issue now is that there is no way for the client to know if the server is updated. So each time we post a message we need to refresh the page to see the new messages.

To solve this we can add a push notification system that will send messages from server to client. In Node.js we use socket.io.

Socket.io

Socket.IO is a JavaScript library for realtime web applications. It enables realtime, bi-directional communication between web clients and server. It has two parts: a client-side library that runs in the browser, and a server-side library for Node.js. Socket.io enables real-time bidirectional event-based communication.

To install socket.io:

npm install -s socket.io

we also need an HTTP package for Socket.io to work:

npm install -s http

Add the following code to server.js:

var http = require(‘http’).Server(app); var io = require(‘socket.io’)(http);

And we can create a connection:

io.on(‘connection’, () =>{ console.log(‘a user is connected’) })

In the index.html add the following tag:

Now we need to create an emit action when a message is created in server.js. So the post route becomes this:

app.post('/messages', (req, res) => { var message = new Message(req.body); message.save((err) =>{ if(err) sendStatus(500); io.emit('message', req.body); res.sendStatus(200); }) })

And in the client side script tag in index.html, add the following code:

var socket = io(); socket.on(‘message’, addMessages)

So each time a message is posted, the server will update the messages in the message div.

Great!!

This is very basic application that we can create in Node.js. There is lot of scope for improvement. The finished code can be found in //github.com/amkurian/simple-chat

server.js

var express = require('express'); var bodyParser = require('body-parser') var app = express(); var http = require('http').Server(app); var io = require('socket.io')(http); var mongoose = require('mongoose'); app.use(express.static(__dirname)); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})) var Message = mongoose.model('Message',{ name : String, message : String }) var dbUrl = 'mongodb://username:[email protected]:57981/simple-chat' app.get('/messages', (req, res) => { Message.find({},(err, messages)=> { res.send(messages); }) }) app.get('/messages', (req, res) => { Message.find({},(err, messages)=> { res.send(messages); }) }) app.post('/messages', (req, res) => { var message = new Message(req.body); message.save((err) =>{ if(err) sendStatus(500); io.emit('message', req.body); res.sendStatus(200); }) }) io.on('connection', () =>{ console.log('a user is connected') }) mongoose.connect(dbUrl ,{useMongoClient : true} ,(err) => { console.log('mongodb connected',err); }) var server = http.listen(3001, () => { console.log('server is running on port', server.address().port); });

Hope this was helpful in understanding some basic concepts.

Some useful links

Socket.IO

SOCKET.IO 2.0 IS HERE FEATURING THE FASTEST AND MOST RELIABLE REAL-TIME ENGINE ~/Projects/tweets/index.js var io =…socket.ioExpress - Node.js web application framework

Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and…expressjs.com

//mongoosejs.com/