Add real-time booking collaboration via WebSocket
- Backend: /ws relay endpoint (@fastify/websocket) - Frontend: useHotelSocket hook with lock/unlock/booking events - Calendar: lock overlay with diagonal stripes shows other manager editing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
40
backend/src/routes/ws.ts
Normal file
40
backend/src/routes/ws.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { FastifyPluginAsync } from 'fastify'
|
||||
import fastifyWebsocket from '@fastify/websocket'
|
||||
import type { WebSocket } from 'ws'
|
||||
|
||||
// hotel slug → set of connected clients
|
||||
const hotelRooms = new Map<string, Set<WebSocket>>()
|
||||
|
||||
const ws: FastifyPluginAsync = async (fastify) => {
|
||||
await fastify.register(fastifyWebsocket)
|
||||
|
||||
fastify.get<{ Querystring: { hotel?: string; token?: string } }>(
|
||||
'/ws',
|
||||
{ websocket: true },
|
||||
(socket, request) => {
|
||||
const hotel = request.query.hotel ?? ''
|
||||
if (!hotel) { socket.close(4001, 'hotel required'); return }
|
||||
|
||||
if (!hotelRooms.has(hotel)) hotelRooms.set(hotel, new Set())
|
||||
hotelRooms.get(hotel)!.add(socket)
|
||||
|
||||
socket.on('message', (raw) => {
|
||||
const data = raw.toString()
|
||||
const peers = hotelRooms.get(hotel)
|
||||
if (!peers) return
|
||||
peers.forEach(client => {
|
||||
if (client !== socket && client.readyState === 1) {
|
||||
client.send(data)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
socket.on('close', () => {
|
||||
hotelRooms.get(hotel)?.delete(socket)
|
||||
if (hotelRooms.get(hotel)?.size === 0) hotelRooms.delete(hotel)
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export default ws
|
||||
Reference in New Issue
Block a user