admin管理员组文章数量:1432566
I am experiencing issues with WebSocket in my code. When using the deployed URL from Render (), I do not receive notifications on the frontend. However, when using http://localhost:5000, the notifications work as expected on the frontend.
import {
addNotification,
clearNotifications,
} from '@/features/notification/notificationSlice';
import { FC, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import socketIo from 'socket.io-client';
interface SocketComponentProps {
children: React.ReactNode;
}
const SocketComponent: FC<SocketComponentProps> = ({ children }) => {
const dispatch = useDispatch();
const { userInfo } = useSelector((state: any) => state.user);
const currentUserId = userInfo?.user?.id;
const messages = useSelector((state: any) => state.chat.conversations);
useEffect(() => {
const socket = socketIo('', {
transports: ['websocket'],
});
socket.on('connect', () => {
console.log('Connected to WebSocket server:', socket.id);
});
socket.emit('joinNotifications', { userId: currentUserId });
socket.on('notification', (notification) => {
console.log('Notification received:', notification);
dispatch(addNotification(notification));
});
return () => {
socket.disconnect();
socket.off('notification');
};
}, [messages, dispatch]);
return <>{children}</>;
};
export default SocketComponent;
Here is the backend code
const { Server } = require('socket.io');
const app = express();enter code here
app.use('../public', express.static('public'));
app.use(bodyParser.json());
app.use(cors());
app.use(
'/graphql',
graphqlHTTP(async (req, res) => {
const user = await authMiddleware(req, res);
console.log({ user });
return {
schema,
graphiql: true,
context: {
User,
Property,
currentUser: user,
io,
},
};
}),
);
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST'],
},
});
io.on('connection', (socket) => {
socket.on('joinNotifications', ({ userId }) => {
socket.join(userId);
});
});
const port = process.env.PORT || 5000;
if (!module.parent) {
server.listen(port, () => {
logger.info(`server running on port ${port}`);
});
}
module.exports = server;
here is the notification handler
const sendNotification = (io, userId, title, body, url = null) => {
try {
const notification = {
title,
body,
timestamp: new Date(),
read: false,
};
// Add the URL if provided
if (url) {
notification.url = url;
}
// Emit the notification to the user
io.to(userId).emit('notification', notification);
console.log({ notification });
} catch (error) {
console.error(`Error sending notification to user ${userId}:`, error);
}
};
module.exports = sendNotification;
here is the graqhl mutation
requestApproval: {
type: ApprovalType,
args: {
bookingId: { type: GraphQLNonNull(GraphQLID) },
userId: { type: GraphQLNonNull(GraphQLID) },
message: { type: GraphQLString },
},
resolve: async (parent, args, context) => {
const { io } = context;
//<--------- create an approval based on the booking id ---------->
const approval = new Approval({
booking: args.bookingId,
user: args.userId,
message: args.message,
});
const createdApproval = await approval.save();
const booking = await Booking.findById(args.bookingId).populate('user property');
//<---------- find the host who owns that property ---------->
const host = await User.findById(booking.property.user);
const hostEmail = host.email;
const baseUrl = process.env.NODE_ENV === 'production' ? process.env.PROD_URL : process.env.DEV_URL;
const manageShortletUrl = `${baseUrl}/manage-shortlets`;
//<---------- email option for booking request ---------->
const bookingDetails = {
...booking._doc,
startDate: moment(booking.startDate).format('DD MMMM YYYY'),
endDate: moment(booking.endDate).format('DD MMMM YYYY'),
};
const hostMail = {
From: '[email protected]',
To: hostEmail,
Subject: `New Booking Request for ${booking.property.title}`,
HtmlBody: BOOKING_REQUEST_TEMPLATE(host, bookingDetails, manageShortletUrl),
};
const notificationLink = `/review-booking/${booking.property._id.toString()}`;
try {
const result = await client.sendEmail(hostMail);
sendNotification(
io,
host._id.toString(),
'Booking Request',
`You have a new booking request for your property ${booking.property.title}.`,
notificationLink,
);
console.log('sent');
} catch (error) {
console.error('Error sending email to host:', error);
}
return createdApproval;
},
},
I am experiencing issues with WebSocket in my code. When using the deployed URL from Render (https://polis-backend-test.onrender), I do not receive notifications on the frontend. However, when using http://localhost:5000, the notifications work as expected on the frontend.
import {
addNotification,
clearNotifications,
} from '@/features/notification/notificationSlice';
import { FC, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import socketIo from 'socket.io-client';
interface SocketComponentProps {
children: React.ReactNode;
}
const SocketComponent: FC<SocketComponentProps> = ({ children }) => {
const dispatch = useDispatch();
const { userInfo } = useSelector((state: any) => state.user);
const currentUserId = userInfo?.user?.id;
const messages = useSelector((state: any) => state.chat.conversations);
useEffect(() => {
const socket = socketIo('https://polis-backend-test.onrender', {
transports: ['websocket'],
});
socket.on('connect', () => {
console.log('Connected to WebSocket server:', socket.id);
});
socket.emit('joinNotifications', { userId: currentUserId });
socket.on('notification', (notification) => {
console.log('Notification received:', notification);
dispatch(addNotification(notification));
});
return () => {
socket.disconnect();
socket.off('notification');
};
}, [messages, dispatch]);
return <>{children}</>;
};
export default SocketComponent;
Here is the backend code
const { Server } = require('socket.io');
const app = express();enter code here
app.use('../public', express.static('public'));
app.use(bodyParser.json());
app.use(cors());
app.use(
'/graphql',
graphqlHTTP(async (req, res) => {
const user = await authMiddleware(req, res);
console.log({ user });
return {
schema,
graphiql: true,
context: {
User,
Property,
currentUser: user,
io,
},
};
}),
);
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST'],
},
});
io.on('connection', (socket) => {
socket.on('joinNotifications', ({ userId }) => {
socket.join(userId);
});
});
const port = process.env.PORT || 5000;
if (!module.parent) {
server.listen(port, () => {
logger.info(`server running on port ${port}`);
});
}
module.exports = server;
here is the notification handler
const sendNotification = (io, userId, title, body, url = null) => {
try {
const notification = {
title,
body,
timestamp: new Date(),
read: false,
};
// Add the URL if provided
if (url) {
notification.url = url;
}
// Emit the notification to the user
io.to(userId).emit('notification', notification);
console.log({ notification });
} catch (error) {
console.error(`Error sending notification to user ${userId}:`, error);
}
};
module.exports = sendNotification;
here is the graqhl mutation
requestApproval: {
type: ApprovalType,
args: {
bookingId: { type: GraphQLNonNull(GraphQLID) },
userId: { type: GraphQLNonNull(GraphQLID) },
message: { type: GraphQLString },
},
resolve: async (parent, args, context) => {
const { io } = context;
//<--------- create an approval based on the booking id ---------->
const approval = new Approval({
booking: args.bookingId,
user: args.userId,
message: args.message,
});
const createdApproval = await approval.save();
const booking = await Booking.findById(args.bookingId).populate('user property');
//<---------- find the host who owns that property ---------->
const host = await User.findById(booking.property.user);
const hostEmail = host.email;
const baseUrl = process.env.NODE_ENV === 'production' ? process.env.PROD_URL : process.env.DEV_URL;
const manageShortletUrl = `${baseUrl}/manage-shortlets`;
//<---------- email option for booking request ---------->
const bookingDetails = {
...booking._doc,
startDate: moment(booking.startDate).format('DD MMMM YYYY'),
endDate: moment(booking.endDate).format('DD MMMM YYYY'),
};
const hostMail = {
From: '[email protected]',
To: hostEmail,
Subject: `New Booking Request for ${booking.property.title}`,
HtmlBody: BOOKING_REQUEST_TEMPLATE(host, bookingDetails, manageShortletUrl),
};
const notificationLink = `/review-booking/${booking.property._id.toString()}`;
try {
const result = await client.sendEmail(hostMail);
sendNotification(
io,
host._id.toString(),
'Booking Request',
`You have a new booking request for your property ${booking.property.title}.`,
notificationLink,
);
console.log('sent');
} catch (error) {
console.error('Error sending email to host:', error);
}
return createdApproval;
},
},
Share
Improve this question
asked Nov 18, 2024 at 16:40
Favour SamsonFavour Samson
212 bronze badges
1 Answer
Reset to default 0Most likely it is related to the hosting (or server) configuration. Some hosting (like Vercel) does not support sockets. https://vercel/guides/do-vercel-serverless-functions-support-websocket-connections
版权声明:本文标题:javascript - WebSocket notifications not working with deployed Render URL but working locally - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745606972a2665890.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论