fix: make WS handler synchronous — async handler breaks socket.on('message') in @fastify/websocket v8
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,7 +52,7 @@ async function sendPushToOfflineUsers(userIds: string[], payload: object) {
|
||||
}
|
||||
|
||||
export function setupWebSocket(app: FastifyInstance) {
|
||||
(app as any).get('/ws', { websocket: true }, async (socket: any, req: any) => {
|
||||
(app as any).get('/ws', { websocket: true }, (socket: any, req: any) => {
|
||||
let userId: string | null = null;
|
||||
|
||||
try {
|
||||
@@ -64,21 +64,20 @@ export function setupWebSocket(app: FastifyInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uid = userId;
|
||||
|
||||
// Register connection
|
||||
if (!connections.has(userId)) connections.set(userId, new Set());
|
||||
connections.get(userId)!.add(socket);
|
||||
if (!connections.has(uid)) connections.set(uid, new Set());
|
||||
connections.get(uid)!.add(socket);
|
||||
|
||||
// Update last_seen
|
||||
await pool.query('UPDATE users SET last_seen = NOW() WHERE id = $1', [userId]);
|
||||
|
||||
// Notify others that user is online
|
||||
const { rows: memberChats } = await pool.query(
|
||||
'SELECT DISTINCT chat_id FROM chat_members WHERE user_id = $1', [userId]
|
||||
);
|
||||
for (const row of memberChats) {
|
||||
const ids = await getChatMemberIds(row.chat_id);
|
||||
broadcast(ids.filter(id => id !== userId), { type: 'user_online', payload: { userId, online: true } });
|
||||
}
|
||||
// Update last_seen + notify online (fire-and-forget)
|
||||
pool.query('UPDATE users SET last_seen = NOW() WHERE id = $1', [uid]).catch(() => {});
|
||||
pool.query('SELECT DISTINCT chat_id FROM chat_members WHERE user_id = $1', [uid]).then(async ({ rows: memberChats }) => {
|
||||
for (const row of memberChats) {
|
||||
const ids = await getChatMemberIds(row.chat_id);
|
||||
broadcast(ids.filter(id => id !== uid), { type: 'user_online', payload: { userId: uid, online: true } });
|
||||
}
|
||||
}).catch(() => {});
|
||||
|
||||
socket.on('message', async (raw: any, isBinary: boolean) => {
|
||||
try {
|
||||
@@ -199,20 +198,19 @@ export function setupWebSocket(app: FastifyInstance) {
|
||||
});
|
||||
|
||||
socket.on('close', async () => {
|
||||
if (!userId) return;
|
||||
const set = connections.get(userId);
|
||||
const set = connections.get(uid);
|
||||
if (set) {
|
||||
set.delete(socket);
|
||||
if (set.size === 0) {
|
||||
connections.delete(userId);
|
||||
await pool.query('UPDATE users SET last_seen = NOW() WHERE id = $1', [userId]);
|
||||
connections.delete(uid);
|
||||
await pool.query('UPDATE users SET last_seen = NOW() WHERE id = $1', [uid]);
|
||||
|
||||
const { rows: memberChats } = await pool.query(
|
||||
'SELECT DISTINCT chat_id FROM chat_members WHERE user_id = $1', [userId]
|
||||
'SELECT DISTINCT chat_id FROM chat_members WHERE user_id = $1', [uid]
|
||||
);
|
||||
for (const row of memberChats) {
|
||||
const ids = await getChatMemberIds(row.chat_id);
|
||||
broadcast(ids, { type: 'user_online', payload: { userId, online: false } });
|
||||
broadcast(ids, { type: 'user_online', payload: { userId: uid, online: false } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user