NestJS后端向RTK Query前端推送通知失败:Socket监听无响应排查
问题描述
我希望在用户收到关注请求时向其推送通知。目前后端控制台已能显示通知消息,但前端Socket无法监听到通知。
相关代码
前端RTK Query配置
import { createApi } from "@reduxjs/toolkit/query/react"; import { baseQuery } from "./config"; import { io } from "socket.io-client"; export const user = createApi({ endpoints: (builder) => ({ getNotifications: builder.query({ queryFn: () => { return { data: [] } }, async onCacheEntryAdded( arg, { updateCachedData, cacheDataLoaded, cacheEntryRemoved } ) { try { await cacheDataLoaded; const socket = io('http://localhost:8000', { withCredentials: true, }); // 假设当前用户ID已通过认证获取,比如从redux store或auth上下文 const currentUserId = '当前用户的ID'; // 替换为实际获取方式 socket.emit('joinRoom', currentUserId); // 监听通知,修正参数类型 socket.on("notifications", (message) => { updateCachedData((draft) => { draft.push(message); }); }); await cacheEntryRemoved; socket.disconnect(); } catch (err) { console.error('Socket连接或监听出错:', err); } finally { await cacheEntryRemoved; } }, }), }), });
后端followRequest.service代码
async acceptFollowRequest(requestId: string) { // 此处省略获取senderId和receiverId的逻辑 // 创建关注关系:发送者关注接收者 await this.prisma.follower.create({ data: { followerId: senderId, followingId: receiverId, }, }); this.notificationsGateway.sendNotification({ message: `你的关注请求已被用户 ${receiverId} 接受`, userId: senderId, }); }
后端notification.gateway代码
import { WebSocketGateway, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, } from '@nestjs/websockets'; import { Server, Socket } from 'socket.io'; @WebSocketGateway({ cors: { origin: process.env.FRONTEND_URL, credentials: true, }, }) export class NotificationsGateway implements OnGatewayConnection, OnGatewayDisconnect { @WebSocketServer() server: Server; handleConnection(client: Socket) { // 可在此处从客户端连接信息中获取用户ID,比如cookie、token等 // 示例:假设从auth token解析userId // const userId = client.handshake.auth.userId; // 如果需要验证用户,可在此处处理 console.log(`客户端 ${client.id} 已连接`); } handleDisconnect(client: Socket) { console.log(`客户端 ${client.id} 已断开连接`); } // 处理前端加入房间的请求 @SubscribeMessage('joinRoom') handleJoinRoom(client: Socket, userId: string) { client.join(userId); console.log(`客户端 ${client.id} 加入房间:${userId}`); } sendNotification(notification: { message: string; userId: string }) { this.server .to(notification.userId) .emit('notifications', notification.message); console.log(notification.message); } }
问题排查与修复要点
- 房间订阅缺失:后端通过
to(notification.userId)向指定房间发送消息,但前端未加入该用户ID对应的房间。需在前端连接Socket后,发送joinRoom事件传入当前用户ID,后端接收后让客户端加入对应房间。 - 前端监听冗余与类型错误:原代码中两次监听
notifications事件,且第二个监听的参数类型错误(Socket.io回调直接返回数据,而非MessageEvent),需移除冗余监听并修正参数处理。 - 资源清理:在
cacheEntryRemoved后断开Socket连接,避免内存泄漏。 - 用户身份关联:确保后端能正确识别每个连接的用户身份,将Socket连接与用户ID绑定,才能精准推送通知到目标用户。
内容的提问来源于stack exchange,提问作者Damilola Adegbemile
相关产品推荐
相关产品推荐

