以下は、Vue + Laravel 8 を使用して WebSocket をカプセル化し、リアルタイム チャットを実装するための基本的な手順です。
- laravel-websockets パッケージをインストールします。
composer require beyondcode/laravel-websockets
- Laravel プロジェクトで JWT 認証キーを生成します。
php artisan jwt:secret
- Laravel Echo と Pusher JS をインストールします。
npm install laravel-echo pusher-js --save
- WebSocket 接続リクエストをリッスンするために、Laravel プロジェクトに WebSocket ルートを作成します。
use BeyondCode\LaravelWebSockets\WebSocketsServiceProvider;
Route::get('/websocket', function () {
// 加载 WebSocket 服务
app(WebSocketsServiceProvider::class)->boot();
// 认证用户并与当前 WebSocket 连接绑定
auth()->loginUsingId(request()->get('user_id'));
// 开始监听连接请求
RatchetServerIoServer::factory(
new HttpServer(
new WsServer(
app(WebSocketsEventHandler::class)
)
),
env('WEBSOCKET_PORT')
)->run();
// 返回 OK 状态
return response('WebSocket server is running.');
});
WebsocketsEventHandler
WebSocket メッセージを処理するクラスを作成します。
use Illuminate\Support\Facades\Auth;
use BeyondCode\LaravelWebSockets\Events\WebsocketMessageReceived;
class WebsocketsEventHandler implements ShouldQueue
{
public function onMessage(WebsocketMessageReceived $event)
{
// 消息处理逻辑
}
}
ChatMessage
チャット情報を表示し、新しいチャット情報を送信するための Vue コンポーネントを作成します。
<template>
<div>
<div v-for="message in messages" :key="message.id">
{
{ message.user.name }}: {
{ message.text }}
</div>
<form @submit.prevent="send">
<input type="text" v-model="text">
<button type="submit">Send</button>
</form>
</div>
</template>
<script>
import Echo from "laravel-echo";
import Pusher from "pusher-js";
export default {
data() {
return {
messages: [],
text: "",
};
},
mounted() {
this.initEcho();
this.fetchMessages();
},
methods: {
initEcho() {
window.Echo = new Echo({
broadcaster: "pusher",
key: "YOUR_APP_KEY",
cluster: "YOUR_APP_CLUSTER",
forceTLS: true,
authEndpoint: "/api/authenticate",
auth: {
headers: {
Authorization:
"Bearer " + localStorage.getItem("access_token"),
},
},
});
window.Echo.join(`chat`).here((users) => {
console.log(users);
});
window.Echo.channel(`chat`).listen(".message.sent", (event) => {
this.messages.push(event.message);
});
},
fetchMessages() {
axios.get(`/api/chat/messages`).then((response) => {
this.messages = response.data.messages;
});
},
send() {
axios.post(`/api/chat/messages`, {
text: this.text }).then(() => {
this.text = "";
});
},
},
};
</script>
ChatMessageController
チャット メッセージを送受信するための API リクエストを処理するクラスを作成します。
use Illuminate\Http\Request;
use App\Models\Message;
use Illuminate\Support\Facades\Auth;
use BeyondCode\LaravelWebSockets\Events\WebsocketMessageSent;
class ChatMessageController extends Controller
{
public function index()
{
$messages = Message::with('user')->get();
return response()->json([
'messages' => $messages
]);
}
public function store(Request $request)
{
$user = Auth::user();
$message = new Message([
'text' => $request->input('text')
]);
$message->user()->associate($user);
$message->save();
event(new WebsocketMessageSent('chat', [
'user_id' => $user->id,
'text' => $message->text,
]));
}
}
JwtAuthMiddleware
ユーザーを認証し、JWT 認証トークンを返すクラスを作成します。
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Tymon\JWTAuth\Facades\JWTAuth;
class JwtAuthMiddleware
{
public function handle(Request $request, Closure $next)
{
try {
$user = JWTAuth::parseToken()->authenticate();
if ($user) {
$request->merge([
'user_id' => $user->id
]);
return $next($request);
}
} catch (\Throwable $e) {
return new Response('Unauthorized', 401);
}
}
}
- ミドルウェアを登録するために Laravel プロジェクトにルーティングを追加します
JwtAuthMiddleware
。
Route::middleware([JwtAuthMiddleware::class])->group(function () {
// ChatMessageController API 路由
});
このようにして、Vue フロントエンドでチャット メッセージを送信すると、メッセージはWebsocketsEventHandler
バックエンド Laravel プロジェクトのクラスに転送されて処理されます。チャット情報は、WebSocket を使用して接続されているすべてのクライアントにブロードキャストされます。同時に、Vue フロントエンドがリッスンしてサブスクライブした後、WebSocket サーバーから送信されたチャット情報を受信して、リアルタイム チャット機能を実現できます。