RealTime Chat Application using Laravel & Vuejs [P2]
This post hasn't been updated for 6 years
Chat real-time với 1 user
Đầu tiên để ta cần khai báo 1 route để xem ta muốn chat với user nào
Route::get('/chat/{id}', 'ChatController@show')->name('chat.show');
// ChatController
public function show($userId)
{
$friend = User::find($userId);
return view('chat-room.show', compact('friend'));
}
// show.blade.php
<meta name="userId" content="{{ Auth::check() ? Auth::user()->id : 'null' }}">
<meta name="friendId" content="{{ $friend->id }}">
<div class="col-md-12" style="padding: 0" id="box-private">
<div class="panel panel-primary">
<div class="panel-heading friend-name">
<span class="panel-title">{{$friend->name}}</span>
</div>
</div>
</div>
Get history
Trên đây chỉ là giao diện bên ngoài thôi. Ta sẽ cần phải lấy lịch sử chat & làm form chat nữa
Route::post('/history/{chatRoomId}', 'ChatRoomController@history')->name('chat-room.history');
// ChatController
public function history(Request $request, $chatRoomId)
{
return ChatRoom::where(function ($query) use ($chatRoomId) {
$query->where('user_id', Auth::user()->id)
->where('friend_id', $chatRoomId);
})->orWhere(function ($query) use ($chatRoomId) {
$query->where('friend_id', Auth::user()->id)
->where('user_id', $chatRoomId);
})->orderBy('created_at', 'asc')
->with(['user'])
->get();
}
Ở đây, hàm history
mình sẽ lấy tất cả record trong bảng chat_room
của A gửi cho B hoặc B gửi cho A. Vậy nên mới có chỗ condition orWhere
Tất nhiên hàm này là 1 API sẽ được gọi qua axios
của Vue.
// app.js
const app = new Vue({
el: '#app',
data: {
chats: '',
},
created() {
const friendId = $('meta[name="friendId"]').attr('content');
if (friendId != undefined) {
axios.post('/chat-room/history/' + friendId).then((response) => {
this.chats = response.data;
});
}
}
});
Ở đoạn code trên, khi app được khởi tạo ta sẽ gọi đến api history
để lấy lịch sử chat của user đang login và người bạn đang select & được lưu vào biến chats
. Giở ta sẽ tạo component để hiển thị form chat
Create Form chat
<template>
<div class="box box-primary direct-chat direct-chat-primary">
<div class="direct-chat-messager">
<div class="direct-chat-msg clearfix" v-for="msg in chats" :class="[msg.user_id == user_id ? 'right' : '']">
<div class="direct-chat-info clearfix"></div>
<img class="direct-chat-img" :src="msg.user.avatar" alt="Message User Image">
<div class="direct-chat-text">{{msg.chat}}</div>
</div>
</div>
<div class="box-footer">
<chat-room-composer :user_id="user_id" :friend_id="friend_id" :history="chats"></chat-room-composer>
</div>
</div>
</template>
<script>
export default {
props: ['chats', 'user_id', 'friend_id'],
}
</script>
Ở trên ta đã hiển thị lịch sử chat của 2 user và ở dưới ta sẽ cần 1 form để nhập đoạn chat mới. Bạn có thể để í là ta sẽ dùng thêm 1 component nữa chat-room-composer
để làm việc này
<template>
<div class="input-group">
<input type="text" class="form-control" :disabled="is_disabled" v-model="chat" v-on:keyup.enter="sendChat" autofocus>
<!--<div class="input-group-append">-->
<!--<button class="btn btn-primary" type="button" v-on:click="sendChat">Send</button>-->
<!--</div>-->
</div>
</template>
<script>
export default {
props: ['user_id', 'friend_id', 'history'],
data() {
return {
chat: '',
is_disabled: false,
}
},
methods: {
sendChat: function (e) {
let data = {
chat: this.chat,
user_id: this.user_id,
friend_id: this.friend_id,
user: {
avatar: $('meta[name=user_avatar]').attr('content'),
},
is_sendmail: !(_.find(this.onlineusers, {id: this.friend_id})),
};
axios.post('/chat-room/sendChat', data).then((response) => {
this.history.push(data);
this.chat = '';
this.is_disabled = false;
$("html, body").animate({scrollTop: $(document).height()}, 100);
}).catch((error) => {
this.is_disabled = false;
});
},
}
}
</script>
Ở component chat-composer
ta có nhận 3 biến từ bên ngoài truyền vào. mục đích là để tạo data khi user submit form chat, sau đó sẽ thêm nội dung đoạn chat đó vào phần lịch sử của 2 user
Và api lưu đoạn chat mới của user sẽ là /chat-room/sendChat
// ChatRoomController.php
public function sendChat(Request $request)
{
$chatRoom = ChatRoom::create([
'user_id' => $request->user_id,
'friend_id' => $request->friend_id,
'chat' => $request->chat
]);
$chatRoom->load('user');
broadcast(new ChatRoomBroadCast($chatRoom))->toOthers();
}
Khi user nhập đoạn chat của họ vào form & ấn nút submit. Ta sẽ gọi 1 api lên server & data là nội dung đoạn chat, user id của 2 user. Sau đó trên server ta sẽ lưu toàn bộ data đó vào database
broadcast(new ChatRoomBroadCast($chatRoom))->toOthers();
Hàm này sẽ bắn nội dung chat đến cho những user khác thông qua broadcast
của laravel
Phần tiếp theo mình sẽ hướng dẫn các bạn config broadcast
để có thể chat real-time giữa các user với nhau cũng như ta sẽ làm tính năng thông báo khi 1 user nào đó online
All Rights Reserved