この記事では、次のテクノロジーを使用してリアルタイムチャットアプリケーションを構築する方法を紹介します。
- Redis
- Node.js + Express.js
- Socket.IO
- Heroku
Redis
Redisはオープンソース(BSDライセンス)のメモリ内データ構造ストアであり、データベース、キャッシュ、メッセージブローカーとして使用されます。文字列、ハッシュ、リスト、セット、範囲クエリを使用した並べ替えられたセット、ビットマップ、ハイパーログログ、半径クエリを使用した地理空間インデックスなどのデータ構造をサポートします。
このアプリケーションチュートリアルでは、Redis™*用のScaleGridホスティングを使用してクラスターの1つに接続します。
Node.js
ChromeのJavaScriptランタイムに基づいて構築されたプラットフォームで、高速でスケーラブルなネットワークアプリケーションを簡単に構築できます。 Node.jsは、イベント駆動型の非ブロッキングI / Oモデルを使用しており、軽量で効率的であるため、分散デバイス間で実行されるデータ集約型のリアルタイムアプリケーションに最適です。
Express.js
Node.jsフレームワーク。 Node.jsは、JavaScriptをWebブラウザーの外部で使用してWebおよびネットワークアプリケーションを作成できるようにするプラットフォームです。これは、他のほとんどのWeb言語と同様に、JavaScriptを使用して、アプリケーションのサーバーおよびサーバー側のコードを作成できることを意味します。
Socket.IO
Webクライアントとサーバー間のリアルタイムの双方向通信を可能にするリアルタイムWebアプリケーション用のJavaScriptライブラリ。 Socket.IOには、ブラウザーで実行されるクライアント側ライブラリとNode.js用のサーバー側ライブラリの2つのコンポーネントがあります。どちらのコンポーネントにもほぼ同じAPIがあります。
Heroku
企業がアプリを構築、配信、監視、スケーリングできるようにするクラウドプラットフォーム。 Herokuプラットフォームは、インフラストラクチャの問題をすべて回避して、アイデアからURLに移行するための最速の方法です。
この記事では、マシンにRedis、Node.js、HerokuToolbeltが既にインストールされていることを前提としています。
セットアップ
フォルダを作成して名前を付けます。 Node.jsはApache/nginxのような特別なサーバーを必要としないため、マシン上のどこにでも作成できます。
ステップ1
npm init
を実行してpackage.jsonファイルを初期化します 。
{ "name": "node-socket-redis-chat-scalegrid", "version": "0.0.1", "description": "A realtime chat application using Redis, Node.js and Socket.IO", "dependencies": { "body-parser": "^1.15.2", "express": "^4.10.2", "redis": "^2.6.3", "socket.io": "^1.7.1" }, "main": "index.js", "scripts": { "start": "node index.js" }, "engines": { "node": "4.1.1" } }
ステップ2
次の依存関係をインストールします:
- expressjs
- socketio
- redis
…およびその他のユーティリティメソッド:
- ボディパーサー
次のコマンドを実行します:
npm install --save expressjs socket.io redis body-parser
ステップ3
CSSファイルとJSファイルを保存するためのパブリックフォルダーを作成します:
/public/css/main.css /public/js/main.js
ステップ4:
メインのHTMLファイルを保存するためのビューフォルダを作成します:
/views/index.html
ステップ5:
creds.json
を作成します Redis™クラスターに接続するための資格情報を含むファイル。次の形式に従う必要があります:
{ "user": "", "password": "", "host": "", "port": 6379 }
ステップ6:
index.js
を作成します Node.jsコードをホストし、Herokuの開始点として機能するファイル。
ステップ7:
.gitignore
を追加します ファイルを作成して、node_modulesフォルダーがHerokuにチェックインされないようにします:
node_modules
7番目のステップを完了すると、次の構造になります。
. ├── creds.json ├── index.js ├── package.json ├── public │ ├── css │ │ └── main.css │ └── js │ └── main.js └── views └── index.html
ステップ8
これですべてがセットアップされたので、バックエンドコードの記述を開始できます。まず、すべてのモジュールを取り込む必要があります。そこで、index.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 fs = require('fs'); var creds = ''; var redis = require('redis'); var client = ''; var port = process.env.PORT || 8080; // Express Middleware for serving static // files and parsing the request body app.use(express.static('public')); app.use(bodyParser.urlencoded({ extended: true })); // Start the Server http.listen(port, function() { console.log('Server Started. Listening on *:' + port); }); // Store people in chatroom var chatters = []; // Store messages in chatroom var chat_messages = [];
コードの記述を開始する前に、Redisを実行しているクラスターが必要です。幸い、ScaleGridforRedis™は高性能のワンクリックでフルマネージドのホスティングソリューションを提供します。
まだメンバーでない場合は、ここで30日間の無料トライアルにサインアップできます。
それ以外の場合は、ダッシュボードにログインして、Redis™セクションの下に新しいRedis™クラスターを作成します。
クラスターの作成が完了したら、上記の情報をメモして、creds.json
の関連フィールドに追加します。 ファイル。
資格情報の設定が完了したので、クラスターに接続してキーと値のペアの保存を開始するRedisクライアントをノードに作成する準備が整いました。
次のコードをindex.jsファイルに追加します。
// Read credentials from JSON fs.readFile('creds.json', 'utf-8', function(err, data) { if(err) throw err; creds = JSON.parse(data); client = redis.createClient('redis://' + creds.user + ':' + creds.password + '@' + creds.host + ':' + creds.port); // Redis Client Ready client.once('ready', function() { // Flush Redis DB // client.flushdb(); // Initialize Chatters client.get('chat_users', function(err, reply) { if (reply) { chatters = JSON.parse(reply); } }); // Initialize Messages client.get('chat_app_messages', function(err, reply) { if (reply) { chat_messages = JSON.parse(reply); } }); }); });
上記のコードは2つのことを行います:
-
creds.json
からクレデンシャルを読み取ります キー値操作の実行に使用されるRedisクライアントを作成します - クライアントの準備ができたら、
chatters
にデータを入力します およびchat_messages
そのため、新しいメンバーが参加すると、チャットの履歴を見ることができます。
チャットアプリケーションを処理するためのAPIをいくつか作成します。次のAPIが必要です:
- 部屋に参加[POST]
- 部屋を出る[POST]
- メッセージを送信[POST]
- メッセージを取得[GET]
- メンバーを取得[GET]
入室APIから始めましょう。これは、新しいユーザーが最初にアプリケーションを起動してチャットルームに参加しようとしたときに呼び出されます。
// API - Join Chat app.post('/join', function(req, res) { var username = req.body.username; if (chatters.indexOf(username) === -1) { chatters.push(username); client.set('chat_users', JSON.stringify(chatters)); res.send({ 'chatters': chatters, 'status': 'OK' }); } else { res.send({ 'status': 'FAILED' }); } });
チャットルームを離れるためのAPIがあります:
// API - Leave Chat app.post('/leave', function(req, res) { var username = req.body.username; chatters.splice(chatters.indexOf(username), 1); client.set('chat_users', JSON.stringify(chatters)); res.send({ 'status': 'OK' }); });
メッセージの送信と保存:
// API - Send + Store Message app.post('/send_message', function(req, res) { var username = req.body.username; var message = req.body.message; chat_messages.push({ 'sender': username, 'message': message }); client.set('chat_app_messages', JSON.stringify(chat_messages)); res.send({ 'status': 'OK' }); });>
部屋にあるすべてのメッセージを取得する:
// API - Get Messages app.get('/get_messages', function(req, res) { res.send(chat_messages); });
すべてのメンバーを取得する:
// API - Get Chatters app.get('/get_chatters', function(req, res) { res.send(chatters); });
すべてのAPIを設定したら、次のような特定のプロパティが更新されたときにイベントを発行するようにSocket.IOコードを記述する必要があります。
- 部屋数
- メッセージ
// Socket Connection // UI Stuff io.on('connection', function(socket) { // Fire 'send' event for updating Message list in UI socket.on('message', function(data) { io.emit('send', data); }); // Fire 'count_chatters' for updating Chatter Count in UI socket.on('update_chatter_count', function(data) { io.emit('count_chatters', data); }); });
これらのイベントは、フロントエンドでSocket.IOライブラリによって取得され、UIが更新されます。
ステップ9
次に、ユーザーがログインしてチャットできるようにするUIを作成する必要があります。
index.html
を開きます ファイルを作成し、次のコードを追加します:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Node.js + Socket.io + Redis Chat | ScaleGrid</title> <link rel="stylesheet" href="css/main.css"> </head> <body> <div class="container"> <h1>Node.js + Socket.io + Redis Chat | ScaleGrid</h1> <div class="join-chat"> <label for="username">Username:</label> <input type="text" id="username" name="username" /> <input type="button" id="join-chat" value="Join Chat" /> </div><br /> <div class="chat-info"></div><br /> <div class="chat"> <div class="messages"></div> <textarea name="message" id="message" cols="90" rows="5" placeholder="Enter your message..."></textarea><br /><br /> <input type="button" id="send-message" data-username="" value="Send Message"> <input type="button" id="leave-chat" data-username="" value="Leave Chat"> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.6.0/socket.io.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script src="js/main.js"></script> </body> </html>
ステップ10
HTMLを機能させるには、部屋への参加、退会、メッセージの送信などのさまざまな操作を処理するJavaScriptAJAXイベントを追加する必要があります。
次のコードはおしゃべりの数を取得するため、部屋の合計人数に関するUIを更新できます。
$.get('/get_chatters', function(response) { $('.chat-info').text("There are currently " + response.length + " people in the chat room"); chatter_count = response.length; //update chatter count });
このコードを使用すると、ユーザーはチャットルームに参加できます。ユーザー名は一意であり、複製することはできません。
$('#join-chat').click(function() { var username = $.trim($('#username').val()); $.ajax({ url: '/join', type: 'POST', data: { username: username }, success: function(response) { if (response.status == 'OK') { //username doesn't already exists socket.emit('update_chatter_count', { 'action': 'increase' }); $('.chat').show(); $('#leave-chat').data('username', username); $('#send-message').data('username', username); $.get('/get_messages', function(response) { if (response.length > 0) { var message_count = response.length; var html = ''; for (var x = 0; x < message_count; x++) { html += "<div class='msg'><div class='user'>" + response[x]['sender'] + "</div><div class='txt'>" + response[x]['message'] + "</div></div>"; } $('.messages').html(html); } }); $('.join-chat').hide(); //hide the container for joining the chat room. } else if (response.status == 'FAILED') { //username already exists alert("Sorry but the username already exists, please choose another one"); $('#username').val('').focus(); } } }); });
ユーザーがチャットルームを離れることを許可するためのコードは次のとおりです:
$('#leave-chat').click(function() { var username = $(this).data('username'); $.ajax({ url: '/leave', type: 'POST', dataType: 'json', data: { username: username }, success: function(response) { if (response.status == 'OK') { socket.emit('message', { 'username': username, 'message': username + " has left the chat room.." }); socket.emit('update_chatter_count', { 'action': 'decrease' }); $('.chat').hide(); $('.join-chat').show(); $('#username').val(''); alert('You have successfully left the chat room'); } } }); });
メッセージを送信するたびに実行されるコードは次のとおりです。
$('#send-message').click(function() { var username = $(this).data('username'); var message = $.trim($('#message').val()); $.ajax({ url: '/send_message', type: 'POST', dataType: 'json', data: { 'username': username, 'message': message }, success: function(response) { if (response.status == 'OK') { socket.emit('message', { 'username': username, 'message': message }); $('#message').val(''); } } }); });
以下は、バックエンドからのイベントをリッスンしてUIを更新するSocket.IOコードです。たとえば、メッセージ領域に新しいメッセージを追加したり、おしゃべりカウントを更新したりします。
socket.on('send', function(data) { var username = data.username; var message = data.message; var html = "<div class='msg'><div class='user'>" + username + "</div><div class='txt'>" + message + "</div></div>"; $('.messages').append(html); }); socket.on('count_chatters', function(data) { if (data.action == 'increase') { chatter_count++; } else { chatter_count--; } $('.chat-info').text("There are currently " + chatter_count + " people in the chat room"); });
これで完了です。 npm start
を使用してサーバーを起動します 複数のブラウザウィンドウを開いて、複数のユーザーをシミュレートします。
アプリケーションのデモはこちらから入手できます:https://node-socket-redis-chat.herokuapp.com/
このアプリケーションをHerokuにデプロイするには、ドキュメントを確認してください:https://devcenter.heroku.com/categories/deployment
ソースコード全体はGitHubでも入手でき、フォークして作業できます:https://github.com/Scalegrid/code-samples/tree/sg-redis- node-socket-chat / redis-node-socket-chat
いつものように、すばらしいものを作成する場合は、@scalegridioについてツイートしてください。
Redis™の管理とホスティングについてサポートが必要な場合は、専門サービスを利用して業務を簡素化しましょう。