Laravel Echo thật tuyệt vờiphp artisan make:event ChatMessageWasReceived
Những ứng dụng hay không thể thiếu WebSockets được. Bạn có thể làm Tool chat online, Notification, … và rất nhiều những ứng dụng real time khác. Với Laravel Echo mọi thứ càng trở nên đơn giản. Ý tưởng Xây dựng chức năng chát trực tuyến với multiple rooms. Hình ...
Những ứng dụng hay không thể thiếu WebSockets được. Bạn có thể làm Tool chat online, Notification, … và rất nhiều những ứng dụng real time khác. Với Laravel Echo mọi thứ càng trở nên đơn giản.
Ý tưởng
Xây dựng chức năng chát trực tuyến với multiple rooms.
Hình dung trước khi làm
Ứng dụng Chat online thì chắc chắn cần 1 WebSocket để lắng nghe dữ liệu gửi lên rồi. Ok sử dụng laravel-echo-server cho nó máu. Phía client khi nhận được dữ liệu từ Broadcasting sẽ hiển thị dữ liệu trực tiếp tới người dùng, chơi luôn Vuejs.
Bắt đầu thôi
Đầu tiên tạo 1 event trong Laravel
1 2 3 |
php artisan make:event ChatMessageWasReceived |
Kiểm tra có file nào mới không nào app/Events/ChatMessageWasReceived.php done!
Trong file có 1 method khá quan trọng
1 2 3 4 5 6 |
public function broadcastOn() { return new PrivateChannel('channel-name'); } |
Để đơn giản mình sẽ ko sử dụng Private channel nữa mà sử dụng Public channel trong bài này thay đổi lại sẽ như sau
1 2 3 4 5 6 7 8 |
public function broadcastOn() { return [ "chat-room.1" ]; } |
Tiếp theo ứng dụng chat phải có nơi lưu trữ dữ liệu, Tiến hành tạo migration thôi.
1 2 3 |
php artisan make:model ChatMessage --migration |
Với nội dung khá đơn giản
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
... class CreateChatMessagesTable extends Migration { public function up() { Schema::create('chat_messages', function (Blueprint $table) { $table->increments('id'); $table->string('message'); $table->integer('user_id')->unsigned(); $table->timestamps(); }); } public function down() { Schema::drop('chat_messages'); } } |
Quay trở lại với class app/Events/ChatMessageWasReceived.php truyền 1 số tham số vào như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
... class ChatMessageWasReceived extends Event implements ShouldBroadcast { use InteractsWithSockets, SerializesModels; public $chatMessage; public $user; public function __construct($chatMessage, $user) { $this->chatMessage = $chatMessage; $this->user = $user; } public function broadcastOn() { return [ "chat-room.1" ]; } } |
Các bạn nhớ Implements ShouldBroadcast interface vào nhé.
Ok rồi bây giờ mình sẽ sử dụng Command để gửi đi 1 thông điệp cho client. Tạo 1 command thôi
1 2 3 |
php artisan make:command SendChatMessage |
1 file mới được sinh ra app/Console/Commands/SendChatMessage.php có nội dung như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
... class SendChatMessage extends Command { protected $signature = 'chat:message {message}'; protected $description = 'Send chat message.'; public function handle() { // Fire off an event, just randomly grabbing the first user for now $user = AppUser::first(); $message = AppChatMessage::create([ 'user_id' => $user->id, 'message' => $this->argument('message') ]); event(new AppEventsChatMessageWasReceived($message, $user)); } } |
Open app/Console/Kernel.php và thêm vào params như sau
1 2 3 4 5 6 7 8 9 |
... class Kernel extends ConsoleKernel { protected $commands = [ CommandsSendChatMessage::class, ]; ... |
Ok vậy là xong Bây giờ mỗi khi gửi 1 thông điệp chúng ta sẽ sử dụng command như sau
1 2 3 |
php artisan chat:message "Howdy everyone" |
Ok thông điệp này sẽ được gửi tới đâu, Mình sẽ gửi nó đến 1 websocket để nhận dữ liệu như bên trên mình đã nói sẽ sử dụng laravel-echo-server
1 2 3 |
npm install -g laravel-echo-server |
Khi đã kéo xong package laravel-echo-server
Khởi tạo cho project
1 2 3 |
laravel-echo-server init |
Nó sẽ sinh ra 1 file laravel-echo-server.json Các bạn cấu hình file đó theo môi trường của các bạn nhé, Ở đây mình sẽ sử dụng redis làm db và open port 6001 default của broadcast.
Open file .env và cấu hình tiếp broadcast như sau
1 2 3 4 5 6 |
BROADCAST_DRIVER=redis CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync |
Khởi động WebSocket
1 2 3 |
laravel-echo-server start |
Các bạn có thể check port 6001 đã hoạt động chưa nhé với linux
1 2 3 |
netstat -antp | grep LISTEN |
Nếu thấy port 6001 đang lắng nghe thì đã thành công rồi đó. *_^
Tiếp theo config tiếp để client nhận được thông tin. Open resouces/assets/js/app.js và thêm vào nội dung sau
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import Echo from "laravel-echo" window.Echo = new Echo({ broadcaster: 'socket.io', host: 'http://yourdomain.dev:6001' }); Echo.channel('chat-room.1') .listen('ChatMessageWasReceived', (e) => { console.log(e.user, e.chatMessage); }); |
Khá ổn rồi đây bây giờ hãy chạy gulp hoặc gulp watch .
Chèn vào HTML 2 file javascript sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<html> <head> ... <meta name="csrf-token" content="{{ csrf_token() }}"> ... </head> <body> ... <script src="js/app.js"></script> <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script> </body> </html> |
Vậy là hoàn thành. Các bạn có thể test thử
1 2 3 |
php artisan chat:message "Howdy everyone" |
Thông điệp trên sẽ được lưu vào database và truyền lên cho WebSocket qua port 6001 sử dụng protocol TCP sau đó gửi lại phía client để Laravel Echo nhận thông điệp và hiển thị cho các bạn qua consolog. Cứ mỗi lần gửi thông điệp lên là consolog lại hiển thị dữ liệu ngay lập tức. Bài viết cũng khá dài rồi mình sẽ không hướng dẫn cụ thể để làm hoàn chỉnh 1 ứng dụng chat sử dụng vuejs nữa. Mình sẽ để dành nó vào bài sau vậy. Cảm ơn các bạn đã đọc. Chúc các bạn thành công nhé .!
Reference
Bài viết có tham khảo qua các tài liệu
https://mattstauffer.co/blog/introducing-laravel-echo https://laravel.com/docs/5.3/broadcasting#defining-broadcast-events https://laracasts.com/lessons/introducing-laravel-echo
Techtalk via Viblo