Giới thiệu về laravel echo ứng dụng websocket và vuejs
This post hasn't been updated for 3 years
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
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
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
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.
php artisan make:model ChatMessage --migration
Với nội dung khá đơn giản
...
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
...
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
php artisan make:command SendChatMessage
1 file mới được sinh ra app/Console/Commands/SendChatMessage.php
có nội dung như sau
...
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 = \App\User::first();
$message = \App\ChatMessage::create([
'user_id' => $user->id,
'message' => $this->argument('message')
]);
event(new \App\Events\ChatMessageWasReceived($message, $user));
}
}
Open app/Console/Kernel.php
và thêm vào params như sau
...
class Kernel extends ConsoleKernel
{
protected $commands = [
Commands\SendChatMessage::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
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
npm install -g laravel-echo-server
Khi đã kéo xong package laravel-echo-server
Khởi tạo cho project
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
BROADCAST_DRIVER=redis
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
Khởi động WebSocket
laravel-echo-server start
Các bạn có thể check port 6001 đã hoạt động chưa nhé với linux
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
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
<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ử
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
All Rights Reserved