我在使用 laravel reverb 和 nextjs 实时接收消息时遇到问题 在 privateChannel 上成功授权后,我没有收到任何事件作为响应。
事件类MessageSent: 我在这里使用 privateChannel 向特定用户发送消息
<?php
namespace App\Events;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;**your text**
public $message;
public $userId;
/**
* Create a new event instance.
*/
public function __construct($userId,$message)
{
$this->userId = $userId;
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [
new PrivateChannel('chat.'.$this->userId),
];
}
public function broadcastAs(){
return 'message-sent';
}
public function broadcastWith() : array{
return [
'message' => $this->message,
];
}
}
频道路线:
Broadcast::channel('chat.{userId}', function ($user, $userId) {
return (int) $user->id === (int) $userId;
});
引导程序/app.php:
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: [__DIR__.'/../routes/api.php',__DIR__.'/../routes/auth.php'],
commands: __DIR__.'/../routes/console.php',
// channels: __DIR__.'/../routes/channels.php',
health: '/up',
)
->withBroadcasting(
__DIR__.'/../routes/channels.php',
['prefix'=>'api','middleware'=>['auth:sanctum']],
)
->withMiddleware(function (Middleware $middleware) {
$middleware->api(prepend: [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
]);
$middleware->alias([
'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class,
]);
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
消息控制器:
public function sendMessage(Request $request,string $receiverId){
$authUserId = Auth::user()->id;
$request->validate([
'message'=>['required']
]);
$message = new Message();
$message->sender_id = $authUserId;
$message->receiver_id = $receiverId;
$message->message = $request->message;
$message->save();
event(new MessageSent($receiverId,$request->message));
return response()->json([
'message'=>'Message has sent successfully'
]);
}
Nextjs ** 用于与 Laravel Reverb 服务器通信的 Echo 配置:**
import { useEffect, useState } from 'react';
import axios from './axios';
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
import Cookies from 'js-cookie'; // Import the js-cookie library
const useEcho = () => {
const [echoInstance, setEchoInstance] = useState(null);
useEffect(() => {
// Get the Bearer token from cookies
const token = Cookies.get('token');
// Create the Echo instance here
const echo = new Echo({
broadcaster: 'reverb',
key: process.env.NEXT_PUBLIC_REVERB_APP_KEY,
authorizer: (channel) => {
return {
authorize: (socketId, callback) => {
axios
.post(
'/api/broadcasting/auth',
{
socket_id: socketId,
channel_name: channel.name,
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
)
.then((response) => {
callback(false, response.data);
})
.catch((error) => {
callback(true, error);
});
},
};
},
wsHost: process.env.NEXT_PUBLIC_REVERB_HOST,
wsPort: process.env.NEXT_PUBLIC_REVERB_PORT,
wssPort: process.env.NEXT_PUBLIC_REVERB_PORT,
forceTLS: (process.env.NEXT_PUBLIC_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
setEchoInstance(echo);
}, []);
return echoInstance;
};
export default useEcho;
收听私人频道:
echo.private(`chat.${user.id}`)
.listen('message-sent', (event) => {
console.log(event)
});
}
我收到了对私人频道进行身份验证的成功响应。 图片
但是在向特定用户发送消息后,该事件没有任何响应
我厌倦了运行和排队作业命令和混响服务器,但没有工作
此设置解决了我的问题:
const setEcho = () => {
window.Echo = new Echo({
broadcaster: 'reverb',
key: process.env.NEXT_PUBLIC_REVERB_APP_KEY,
wsHost: process.env.NEXT_PUBLIC_REVERB_HOST,
wsPort: process.env.NEXT_PUBLIC_REVERB_PORT ?? 80,
wssPort: process.env.NEXT_PUBLIC_REVERB_PORT ?? 443,
cluster: 'us2',
forceTLS: (process.env.NEXT_PUBLIC_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws'],
logToConsole: true,
authEndpoint: '/broadcasting/auth',
auth: {
headers: {
Authorization: `Bearer ${cookies.get(COOKIE_KEYS.token)}`,
},
},
});