vue 前段 laravel8后端 封装websocket 实现实时聊天

以下是使用 Vue + Laravel 8 封装 WebSocket 实现实时聊天的基本步骤:

  1. 安装 laravel-websockets 包。
composer require beyondcode/laravel-websockets
  1. 在 Laravel 项目中生成 JWT 认证密钥:
php artisan jwt:secret
  1. 安装 Laravel Echo 和 Pusher JS:
npm install laravel-echo pusher-js --save
  1. 在 Laravel 项目中创建 WebSocket 路由,用于监听 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.');
});
  1. 创建 WebsocketsEventHandler 类,用于处理 WebSocket 消息:
use Illuminate\Support\Facades\Auth;
use BeyondCode\LaravelWebSockets\Events\WebsocketMessageReceived;

class WebsocketsEventHandler implements ShouldQueue
{
    
    
    public function onMessage(WebsocketMessageReceived $event)
    {
    
    
        // 消息处理逻辑
    }
}
  1. 创建 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>
  1. 创建 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,
        ]));
    }
}
  1. 创建 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);
        }
    }
}
  1. 在 Laravel 项目中添加路由,用于注册 JwtAuthMiddleware 中间件:
Route::middleware([JwtAuthMiddleware::class])->group(function () {
    
    
    // ChatMessageController API 路由
});

这样,当你在 Vue 前端发送聊天信息时,该信息将会被转发给后端 Laravel 项目中的 WebsocketsEventHandler 类处理。然后使用 WebSocket 向所有连接的客户端广播该聊天信息。同时,在 Vue 前端监听订阅后,就能够接收 WebSocket 服务器发送的聊天信息,实现实时聊天的功能。

猜你喜欢

转载自blog.csdn.net/qq_27487739/article/details/131004170