search
LoginSignup
25

More than 5 years have passed since last update.

posted at

Sails.js(0.10.x)でSocket.IOを使った超シンプルなチャットサービスを作る

Socket.IOを使った超シンプルなチャットサービスを作る

Sails.jsはとても簡単にシステムが構築できて超便利なんですが、その中でも素晴らしいのがSocket.IOがすでにフレームワークに組み込まれているところ。Sailsを始めて1時間もあればSocet.IOを使ったリアルタイムなんちゃってWebサービスが作れてしまいます。

ただ難点がSails.jsのバージョンアップの速さ。巷にある情報はver0.9以下の情報が多く、Socket.IO以前にそもそも基礎的なアプリを作るのに時間がかかってしまう。というわけで、ver0.10系からSails.jsを始めた人向けに、Socket.IOを使ったリアルタイムチャットサービスの作り方を書きます。

今回作ったソースコードはこちらに置いています。
https://github.com/KeitaMoromizato/chatsample

Socket.IOとは?

簡単に言うと、ブラウザに対してPush通知を行う仕組み。Facebookとかの通知が来るやつと同じですね。

アプリの作成

まずはアプリを作成。名前は適当に「chatsample」にでも。ver0.10.x系からはgenerate apiコマンドでController/Modelが同時に作れちゃいます。今回は超シンプルなチャットサービスなので、MessageController/ModelだけでOK。

$ sails new chatsample
$ cd chatsample
$ sails generate api message

ちょっとした設定

たぶんv0.10から追加されたデータベースのマイグレーション設定。migrateの行のコメントアウトを消しましょう。

config/models.js
   migrate: 'alter'

Controller/Modelの実装

今回はControllerとModelには一切コードを書きません。Controller/Modelさえ作ってしまえば、GET /messageでMessageモデルを全取得、POST /messageでMessageを新規作成という風に全自動でやってくれます。

Viewの作成

こんな感じで、超適当にViewをつくります。views/homepage.ejsがデフォルトのトップページになるので、これをガッツリ書き換えちゃいます。要件はTextAreaと送信ボタン、チャットのタイムラインを表示するためのul要素だけ。こんなところに時間をかけてもしょうがないので適当にいきましょう!

21.png

views/homepage.ejs
<div id="chat-main">
  <ul id="chat-timeline"></ul>
  <div id="chat-form">
    <textarea id="chat-textarea"></textarea>
    <div id="chat-send-button">送信</div>
  </div>
</div>

フロントエンド実装

フロントエンドの実装。まずは結論から、ということで全体像は以下のような感じです。よく分からなくても下で説明していくので大丈夫です。説明を見るのが面倒という方はとりあえずコピペして動かして楽しんでください!

assets/js/main.js
(function() {

  // Socket.IOに接続
  var socket = window.io.connect();

  socket.on('connect', function() {
    // 以下の処理はSocket.IOのconnectメッセージ受信後(接続確立後)
    // に行わないと失敗する
    socket.get("/message", {}, function(messages) {
      for (var i = 0; i < messages.length; i++) {
        $("#chat-timeline").append('<li>' + messages[i].text + '</li>');
      }
    });

    socket.on('message', function(message) {
      if (message.verb == "created") {
        $("#chat-timeline").append('<li>' + message.data.text + '</li>');
      }
    });
  });

  $('#chat-send-button').on('click', function() {
    var $text = $('#chat-textarea');

    var msg = $text.val();

    socket.post("/message", {
      text: msg
    }, function(res) {
      $("#chat-timeline").append('<li>' + res.text + '</li>');
      $text.val('');
    });
  });
})();

Socketの接続

リアルタイム通信のためにSocketを接続します。window.ioは/assets/js/dependencies/sails.io.jsに定義が書かれていたりするのですが、まあ読まなくても大丈夫です。実装や関数が気になったり、業務で使うレベルになったら考えましょう。
とりあえず、window.io.connect()を呼ぶとSocketを接続して、完了すると'connect'イベントが呼ばれるということだけ覚えてたら大丈夫です。

// Socket.IOに接続
var socket = window.io.connect();

socket.on('connect', function() {
  // 接続後の処理
});

保存済みメッセージのGET

まずはすでに保存されているメッセージを取得します。普通ならjQueryでも使って$.get()とか$.ajax()とかやりたいところですが、ここはsocketを使います。socket経由でGETをすると普通にajaxで情報を取得する+「今取得した情報について何か通知があれば教えてね」とサーバーにお願いしにいきます。
ここを$.get()とかにしてしまうとリアルタイム通知が受け取れないのでお気をつけて!

socket.get("/message", {}, function(messages) {
  for (var i = 0; i < messages.length; i++) {
    $("#chat-timeline").append('<li>' + messages[i].text + '</li>');
  }
});

通知の受け取り

次は通知の受け取りかた。これも難しいことは無く、socketのmessageイベントを待ち受ければ良い。コールバックの引数.dataにモデルが入ってくるので、そのtextをリストに表示する。

socket.on('message', function(message) {
  $("#chat-timeline").append('<li>' + message.data.text + '</li>');
});

メッセージの送信

送信ボタンのクリックイベントで実行する処理。ここもGETの時と同様、通常のajax関数ではなくsocekt.postを使う。すると不思議な事に↑でsocket.getした人全員に新しいメッセージが作成された通知が飛ぶ。素晴らしい!

socket.post("/message", {
  text: msg
}, function(res) {
  $("#chat-timeline").append('<li>' + res.text + '</li>');
});

動作確認

実装は本当にこれだけ。というわけで動作確認をしてみる。まずはsailsアプリケーションを起動

$ sails lift

ブラウザを2つ開いてlocalhost:1337にアクセス。この画像を見てもよくわからないが、片方のブラウザで送信した内容がすぐに別のブラウザにも現れる!

22.png

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
25