Reputation: 45
I'm new to websockets and tried to use websockets for pushing notification to user, when function is finished generating exam.
How it is working:
/user/queue/finished-generating-something
and showing button "Generate exam".I don't know if it is correct way to do it, but it was said pinging if exam is finished generating is bad for client.
This code is working on my local server and also worked on production server, but when ~5000 users connected to websocket, it stopped sending messages(subscription to channel and sending message worked, and logs was seen in backend)
Here is my code for backend(Spring):
WebSocketConfig:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic", "/user/queue/finished-generating-exam",
"/user/queue/finished-checking-exam");
registry.setUserDestinationPrefix("/user");
}
// used to add username for each connection
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor =
MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
List<String> authorization = accessor.getNativeHeader("username");
accessor.setUser(new StompPrincipal(authorization.get(0)));
}
return message;
}
});
}
}
ExamService
@Async
public ExamResponse<?> generateExam(String username) {
//Generating exam
webSocketService.sendFinishGenerationExam(username, "created");
}
WebSocketService
@Slf4j
@Service
public class WebSocketService {
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
public void sendFinishGenerationExam(String username, String message) {
simpMessagingTemplate.convertAndSendToUser(username,
"/user/queue/finished-generating-exam", message);
log.info("socket message sent " + message);
}
public void sendCheckingOfExamFinished(String username, String message) {
simpMessagingTemplate.convertAndSendToUser(username,
"/user/queue/finished-checking-exam", message);
log.info("socket message sent " + message);
}
}
And for frontend (React):
import SockJS from "sockjs-client";
import { Client } from "@stomp/stompjs";
//some code
const client = new Client({
webSocketFactory: function () {
return new SockJS(
REACT_APP_WEBSOCKET_URL
);
},
connectHeaders: {
username: username,
},
reconnectDelay: 5000,
debug: function (str) {
console.log(str);
},
});
client.onConnect = function (frame) {
let sessionId = getSessionIdFromUrl(client.webSocket._transport.url);
client.subscribe(
"/user/queue/finished-generating-exam" + "-user" + sessionId,
onMessageReceived
);
};
client.activate();
// some code
Upvotes: 2
Views: 4982
Reputation: 26393
There are always limits. Try creating http(s) service locally and then open 5k connections to it. It will probably fail.
I had bad times with websockets because of these limits, it's a bit hard to tell how many connections your server will be able to handle, while "weight" of those connections depends on your app and resources you have.
You will hit file descriptor limit at minimum. You will hit CPU & RAM limits. You will hit your network limits. There are all kind of things that can go wrong with any connection between devices.
If limit is always at 5k, it sounds like a set artificial limit. If connections start to drop at pretty much random, it's pretty hard to tell.
From all of the headaches i had about websockets now when i need websocket, i don't even try to run classic VM, but better use some cloud service like AWS ApiGateway for Websocket API. If you run some hobby project, sure, socket.io will do perfectly fine or any alternative. Yet once you start to hit such limits it can easily become quite a challenge, at least that's from my personal experience running at least 5 different applications over ws and wss.
Start with file descriptor limit debug, more info here:
https://unix.stackexchange.com/questions/84227/limits-on-the-number-of-file-descriptors
Upvotes: 4