+14

Chat realtime với broadcasting laravel 5.4

Introduction

Chat Realtime là ứng dụng tương tác với người dùng theo thời gian thực. Ví dụ ứng dụng chat của facebook. Trong bài mình sẽ hướng dẫn các bạn sử dụng chức năng brocasting của laravel với driver là pusher để tạo ra ứng dụng realtime.

Cài đặt

  • Mở cmd lên và gõ laravel new demo-chat để tải về framework laravel
  • Vào config/app xóa comment dòng App\Providers\BroadcastServiceProvider::class,
  • php artisan make:auth tạo ra đăng nhập, đăng kí của laravel .
  • Cmd và gõ composer require pusher/pusher-php-server cài server ảo làm trung gian xử lý các dữ liệu với thời gian thực.
  • Vào trang pusher tạo tài khoản, sau đó tạo your app và lấy APP key, secret và ID điền app key trong .env
  • Tạo template file chat trong view, chat.blade.php :
    <div class="panel panel-primary chat">
        <div class="panel-heading">
        <i class="fa fa-user" aria-hidden="true"></i> 
        {{ Auth::user()->name }}
        </div>
        <div class="box-chat">
            <div class="user">
                <span class="message">alo</span>
                <br>
                <span class="author-message"><b>Manager</b></span>
            </div>
        </div>
        <div class="panel-footer clearfix">
            <div class="form-group">
                <div class="input-group">
                    <input type="text" class="form-control message-content" placeholder="Type your message">
                    <input type="hidden" class="room-id" value="1">
                    <input type="hidden" class="user-id" value="{{ Auth::id() }}">
                        <div class="input-group-addon">
                        <a href="#" id="interview-message-send" data-url="#">
                            Send Email
                        </a>
                    </div>
                </div>
            </div>
        </div>
    </div>
  • Tạo ra controller php artisan make:controller MessageController --resource
  • Route web chúng ta sẽ gọi Route::resource('message'', 'MessageController');
  • MessageController@index chúng ta sẽ return view('chat');
  • Sau bước này chúng ta đã hoàn thành gọi giao diện.
  • Tạo file chat.js để ấn nút send thì sẽ tạo request ajax lấy dữ liệu .message-content gửi MessageController@store
// CSRF bảo mật, nếu bạn nào chưa biết đọc tài liệu larave
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

$(document).ready(function() {
	var boxChat = $('.box-chat');
    //Thanh scroll luôn kéo xuống dưới cùng để hiện nội dụng mới nhất
    boxChat[0].scrollTop = boxChat[0].scrollHeight;
    
	$('#interview-message-send').click(function(event) {
		var msgContent = $('.message-content').val();
		$.post('chat', 
			{
				msgContent: msgContent
			}, 
			function(data) {
            
		});
	});
});
  • Dữ liệu ajax sẽ gửi đến MessageController@store xứ lí như sau
  public function store(Request $request)
    {
    /**
      Input chat gửi lên từ ajax ở trên 
     * CandidateController constructor.
     * Ở đây mình chỉ lấy dữ liệu ko lưu vào CSDL, nếu bạn lưu vào CSDL  thì trong bảng đó có user_id, msg, room_id 
     *  sau khi lưu thì lấy được collection của đối tượng đó rồi chúng ta truyền qua $message
     */
        $messge = $request->msgContent; 
        tạo ra một sự kiện gửi đến Pusher
        event(new ChatPosted($message, Auth::user()));
    }
  • Đoạn trên chỉ là gửi ajax lấy dữ liệu đến Controller bình thường. Sau đó khi đã lấy được nội dung chúng ta sẽ tạo ra một event cơ chế giống như là các bạn gọi điện thoại. Chúng ta đã có nội dung bây giờ sẽ tạo ra một sự kiện php artisan make:event MessagePosted class này đóng vài trò như là chúng ta phát ra một tìn hiệu cho sever Pusher biết là vừa có một tin nhắn được gửi.
class MessagePosted implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    protected $message;
    protected $user;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Message $message, User $user)
    {
        $this->user = $user;
        $this->message = $message;
    }
    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
    /**
     *như trên mình đã nói nếu các bạn lưu vào CSDL vào truyền từ biến message qua bên lấy chung ta có thể lấy
     * $this->message->room_id, nhưng ở đấy mình giả sử room là 1
     *Tên room ở đây sẽ là chatroom.1
     */
        return new PresenceChannel('chatroom.'. 1);
    }
}
  • Sau đó chúng ta vào route/channels.php
//Bradcast này giống như route 
// tên channel gióng như ở trên .{id} là tham số, id nó sẽ tự hiểu là id đã được truyền ở trên
Broadcast::channel('chatroom.{id}', function ($user, $id) {
    return $user;
});
  • Đến bước này chúng ta đã xong bước phát tin hiệu , lúc này tín hiệu đã đẩy lên pusher , sau đó chúng ta dùng Laravel Echo để lắng nghe sự kiện từ Pusher để in vào template chat
  • Các bạn vào resource/asset/js/bootraps.js, bỏ dâu ghi chú cho đoạn code này
import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'Key pusher dien vao day'
});

  • Trong file chat.js kia để gửi request ajax bạn cũng có thể viết tiếp đoạn js sau đây vào :
//Join vào phòng chúng ta đã đăng kí ở trên là chatroom.1
Echo.join('chatroom.' + 1)
// lắng nghe sự kiện từ Event MessagePosted, e là Object trả về những dữ liệu chúng ta đã truyền trong __contruct, $message và $user
//Vậy là chúng ta đã có tin nhắn va thông tin người gửi nhiệm vụ chúng ta bây giờ là append html vào box chat 
.listen('MessagePosted', (e) => {
    boxChat.append(e.message);
    boxChat[0].scrollTop = boxChat[0].scrollHeight;
})
  • Bài viết của mình đã giới thiệu qua cho mọi người chat đơn giản trong laravel. Chúc mọi người một ngày vui vẻ! @^@

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí