Help us understand the problem. What is going on with this article?

Laravelで非同期チャットアプリを作ろう(2)

はじめに

この記事では、片方がコメントを送信したら、もう片方の人はリロードしなくても、コメントが表示されるチャットアプリを作っていきたいと思います。

前回:Laravelで非同期チャットアプリを作ろう(1)

完成物

chat2.gif

ソースコード:https://github.com/Alesion30/ChatApp

非同期通信とは

非同期通信とは、ネットワークなどでつながれているコンピュータ間で、送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方式のこと。

参照: 非同期通信 - @IT リッチクライアント用語事典

日常生活の例でいうとこんな感じ。

同期通信

スクリーンショット 2020-01-22 17.47.07.png

非同期通信

スクリーンショット 2020-01-22 17.47.26.png

同期通信の場合は、リクエストを送信したらリロードが入り、他の処理を受け付けなくなるが、非同期通信の場合は、リクエストを送信しても、リロードが入らず別の処理を送信することもできる。

方針

  • APIを作る。(URLにアクセスしたら、jsonデータを返すやつ)
  • JavaScriptで、APIを叩きjsonデータを取得する。
  • ループ処理を用いてjsonデータを、bladeファイルに埋め込む。

APIを作る

HomeController.phpにjsonを返すgetData()という関数を定義する。

app/Http/Controllers/HomeController.php
public function getData()
{
    $comments = Comment::orderBy('created_at', 'desc')->get();
    $json = ["comments" => $comments];
    return response()->json($json);
}

web.phpに、getData()を登録する。

routes/web.php
Route::get('/result/ajax', 'HomeController@getData');

http://localhost/ChatApp/public/result/ajax にアクセスすると、jsonデータが返ってくる。

スクリーンショット 2020-01-22 18.03.40.png

ajaxを使って、jsonを取得する

ajaxを使えるようにするために、app.blade.phpのheadの部分でスクリプトを読み込む。

resources/views/layouts/app.blade.php
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

これはajaxの基本形である。dataTypeには、jsonだけでなく、csvやhtmlも指定できる。

$.ajax({
    url: "result/ajax/",
    dataType: "json",
    success: data => {
      // 成功時の処理
    },
    error: () => {
      // エラー時の処理
    }
})

public/jsフォルダにcomment.jsを新規作成する。5秒ごとに、jsonデータを取得している。

public/js/comment.js
$(function() {
    get_data();
});

function get_data() {
    $.ajax({
        url: "result/ajax/",
        dataType: "json",
        success: data => {
            console.log(data);
        },
        error: () => {
            alert("ajax Error");
        }
    });

    setTimeout("get_data()", 5000);
}

app.blade.phpのbodyタグの一番下に、@yield('js')を入れる。

resources/views/layouts/app.blade.php
        <main class="py-4">
            @yield('content')
        </main>
    </div>

    @yield('js')
</body>

home.blade.phpの一番下で、comment.jsを読み込む。

resources/views/home.blade.php
@section('js')
<script src="{{ asset('js/comment.js') }}"></script>
@endsection

http://localhost/ChatApp/public/home にアクセスして、検証ツールを使うと、5秒ごとにjsonデータが送られてきていることがわかる。

スクリーンショット 2020-01-22 18.16.23.png

comment.jsのsuccessの処理を以下のように書き換えてみる。

public/js/comment.js
success: data => {
    console.log(data.comments);
    for (var i = 0; i < data.comments.length; i++) {
        console.log(data.comments[i].name);
        console.log(data.comments[i].comment);
    }
},

スクリーンショット 2020-01-22 18.29.17.png

ループ処理を用いてjsonデータを、bladeファイルに埋め込む。

home.blade.phpでコメントを表示している部分を書き換える。

resources/views/home.blade.php
<div class="chat-container row justify-content-center">
    <div class="chat-area">
        <div class="card">
            <div class="card-header">Comment</div>
            <div class="card-body chat-card">
                <div id="comment-data"></div>
            </div>
        </div>
    </div>
</div>

JavaScriptで、<div id="comment-data"></div>の中にコメントを埋め込んでいく形になる。

comment.jsのsuccessの処理を以下のように書き換える。

public/js/comment.js
success: data => {
    $("#comment-data")
        .find(".comment-visible")
        .remove();

    for (var i = 0; i < data.comments.length; i++) {
        var html = `
                    <div class="media comment-visible">
                        <div class="media-body comment-body">
                            <div class="row">
                                <span class="comment-body-user" id="name">${data.comments[i].name}</span>
                                <span class="comment-body-time" id="created_at">${data.comments[i].created_at}</span>
                            </div>
                            <span class="comment-body-content" id="comment">${data.comments[i].comment}</span>
                        </div>
                    </div>
                `;

        $("#comment-data").append(html);
    }
},

http://localhost/ChatApp/public/home にアクセスして、コメントを追加するとうまく反映している。

スクリーンショット 2020-01-22 18.32.38.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした