现在我试图配置用户断开的系统。当用户与频道断开连接时,将从redis中删除该用户历史记录。
现在,我要建立从前端调用API的每个地方,以便它可以删除该实体。但是,当连接稳定时,我需要确定从后端原因的用户断开连接,我可以在调试面板上看到连接稳定的消息,并且在调试控制台内也关闭了连接的封闭消息。
因此,我认为我可以跟踪服务器端的连接和断开连接,而不是在前端实现某些内容。因此,有没有办法从后端跟踪连接状态?关闭标签时,我不能使Laravel Reverb断开连接
我正在为您提供整个代码。以便任何人都可以理解正在做什么,下一步该做什么。<?php
namespace App\Listeners;
use App\Events\UserStatus;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
class UserStatusListener
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle(UserStatus $event): void
{
$user_id = $event->user_id;
$status = $event->status;
Log::info("User Status Changed: User ID {$user_id} is now {$status}");
if ($status === "connected") {
// Store user as online in Redis
Redis::setex("user:online:{$user_id}", 300, json_encode([
'user_id' => $user_id,
'status' => 'online',
'last_seen' => now()->toDateTimeString(),
]));
} elseif ($status === "disconnected") {
// Remove user from Redis (user disconnected)
Redis::del("user:online:{$user_id}");
}
}
}
这是我的
UserStatusListner
在确定用户连接状态并将其存储在Redis中的地方。
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class UserStatus implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $user_id;
public $status;
/**
* Create a new event instance.
*/
public function __construct($user_id, $status)
{
$this->user_id = $user_id;
$this->status = $status;
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn()
{
return new PresenceChannel('presence-user-status-'.$this->user_id);
}
public function broadcastAs()
{
return 'user.status'; // Custom event name
}
}
这是我的
UserStatus
Broadcast::channel('presence-user-status-{user_id}', function ($user, $user_id) {
// Check the authenticated user from multiple guards
$staffUser = Auth::guard('staff_users')->user();
$businessUser = Auth::guard('business_users')->user();
$normalUser = Auth::guard('users')->user();
$userData = [];
if ($normalUser && (int) $normalUser->user_id === (int) $user_id) {
$userData = [
'user_id' => $normalUser->user_id,
'type' => "user"
];
}
if ($businessUser && (int) $businessUser->user_id === (int) $user_id) {
$userData = [
'user_id' => $businessUser->user_id,
'type' => "business"
];
}
if ($staffUser && (int) $staffUser->staff_id === (int) $user_id) {
$userData = [
'user_id' => $staffUser->staff_id,
'type' => "staff"
];
}
if (!empty($userData)) {
Redis::setex("user:online:{$user_id}", 300, json_encode([
'user_id' => $userData['user_id'],
'type' => $userData['type'],
'last_seen' => now()->toDateTimeString(),
]));
// Fire the UserStatus event for tracking
event(new UserStatus($userData['user_id'], 'connected'));
return $userData;
}
return false;
});
这是我内部存在频道的频道代码
routes/channels
当用户在线时,我可以将数据存储到redis中,但是当用户断开连接时,我无法跟踪。任何人都有任何建议或任何解决这个问题的方法?N.B-我正在使用Laravel 10版本。
如果不使用WebSocket,则无法实时在线使用用户。您可以做的是创建一个用于投票的终点,并每隔几秒钟定期调用以获取在线用户。在您的情况下,您可以在Redis中设置会话,以每5秒到期一次,并且每4秒(只要您在线),您就调用此端点以验证您的会话再验证5秒钟并获取在线用户。这样,您就可以实现实时效果而无需WebSocket。