Spring boot Web Socket Connection loosing connection on production - java

I am using Angular, Spring Boot, and WebSocket in my project. I'm testing on my local machine socket connection is working fine but when I deployed my build on the production server it is not working properly. sometimes connection was established and sometimes not. I'm new to this technology.
I already configured the message broker and WebSocket application endpoints here is my code
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer, WebSocketConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat").setAllowedOrigins("http://localhost:4200", "https://www.xxxxxx.com/").withSockJS();
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/chatparticipant", "/messages", "/unAssignedParticipant");
}
#Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
container.setMaxBinaryMessageBufferSize(1024000);
return container;
}
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new WebSocketHandler(), "/socket").setAllowedOrigins(Pl4ChatConfig.ALLOWED_ORIGIN);
}
}
we're getting error messages:
WebSocket connection to 'wss://xxxxx.com/ws/709/2pjkwf4q/websocket' failed:

Related

How to get Flutter WebSocket working with spring-boot backend?

I have tried many combinations of the values below, I have no idea why it isn't working. I don't even know if the problem is with frontend or backend setup. I pasted the relevant code parts below.
FLutter says the following when I try to connect (MYIPADDRESS is a valid IP address, the IP address of the pc):
WebSocketChannelException: WebSocketChannelException: WebSocketException: Connection to 'http://MYIPADDRESS:8080/topic/greetings#' was not upgraded to websocket
Here is the backend/spring-boot controller part:
#MessageMapping("/hello")
#SendTo("/topic/greetings")
public String send(final String message) throws Exception {
return message;
}
Here is the backend/spring-boot configuration part:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").withSockJS();
}
}
Here is the frontend/flutter part:
final channel = IOWebSocketChannel.connect(
Uri(
scheme: "ws",
host: "MYIPADDRESS",
port: 8080,
path: "/topic/greetings",
),
);

STOMP connection fails

I have a spring-boot service that provides a STOMP endpoint like so
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/entityUpdates").withSockJS();
}
}
In the Angular frontend, I use this package to connect to the socket:
const url = 'ws://localhost:8080/entityUpdates';
const webSocketClient = new Client({ brokerURL: url });
webSocketClient.activate();
This throws following errors:
WebSocket connection to 'ws://localhost:8080/entityUpdates' failed:
My best guess is that the URL is somehow wrong, or I missed something when I registered the STOMP endpoint, but I can't figure out what it would be.

Spring with STOMP over SockJS and Tomcat not upgrading to Websockets

I am building a Stateless Spring (4.2.4.RELEASE) Solution using STOMP over Websockets with SockJS and a Rest Endpoint using JWT to connect mobile devices with Full Duplex communication. I am using Tomcat 8.0.33 as a Web Server and testing using html with sockjs javascript client. The stomp protocol works fine using the http fallback but I can't make it using only a websocket protocol. I tried CORS in many ways but I am not sure that is a Tomcat Problem or just bad spring configuration. I tested my html even in the same domain and port and SockJS is still falling back into xhr or iframes.
WebScoketConfig.java
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
{
#Override
public void registerStompEndpoints(StompEndpointRegistry registry)
{
RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy();
registry.addEndpoint("/ws").setHandshakeHandler(new DefaultHandshakeHandler(upgradeStrategy))
.setAllowedOrigins("*").withSockJS().setSessionCookieNeeded(false)
.setStreamBytesLimit(512 * 1024)
.setHttpMessageCacheSize(1000)
.setDisconnectDelay(30 * 1000);
}
#Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
registration.taskExecutor().corePoolSize(50);
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry)
{
registry.enableSimpleBroker("/queue/", "/topic/");
// registry.enableStompBrokerRelay("/queue/", "/topic/");
registry.setApplicationDestinationPrefixes("/myapp");
}
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
registration.setMessageSizeLimit(500 * 1024);
registration.setSendBufferSizeLimit(1024 * 1024);
registration.setSendTimeLimit(20000);
}
}
WebSecurityConfig.java
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception
{
http.csrf().disable()
.authorizeRequests()
.antMatchers("/**").permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
}
}
I solved my problem, actually the code was good but the antivirus (Kaspersky) was closing the connection on my client browser just after opened. It forces SockJS to fallback into a different strategy. I tested the client with the antivirus turned off and the Websocket transport was beautifully running. Tested on mac & linux as well.

Extracting Remote endpoint Object from Spring websocket session

In javax websockets we can use something like the follows
Session.getAsyncRemote().sendText(String text)
Session.getBasicRemote().sendText();
How can we send an asynchronous messages using spring websocket.
From WebSocketSession of spring webscockets can we extract RemoteEndPoint and send an async messages
PS Note: I am using Basic Spring websockets...
The configuration and code is as follows:
#Configuration
#EnableWebMvc
#EnableAspectJAutoProxy
#EnableWebSocket
public class WebMVCConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
private static final String ENDPOINT_URL = "/echo";
#Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(socketHandler(), ENDPOINT_URL).setAllowedOrigins("*");
}
#Bean
public WebSocketHandler socketHandler() {
return new WebSocketTestHandler();
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public DefaultHandshakeHandler handshakeHandler() {
WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
policy.setInputBufferSize(8192);
policy.setIdleTimeout(600000);
return new DefaultHandshakeHandler(new JettyRequestUpgradeStrategy(new WebSocketServerFactory(policy)));
}
public class SpringMVCInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { ApplicationConfig.class, RabbitMQConfig.class, RabbitConnectionFactory.class,
WebPropertyPlaceHolderConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
}
#Configuration
public class WebSocketTestHandler extends TextWebSocketHandler {
#Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
log.info("Connection is established to Server....:: Session Open : {}", session.isOpen());
}
#Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
}
#Override
public void afterConnectionClosed(WebSocketSession curSession, CloseStatus status) throws Exception {
}
}
So inside handleTextMessage(WebSocketSession session,TextMessage message) {
Inside this method am creating multiple threads And sending same session Object and some other parameters..Inside each thread am not modifying any session object related parameters but am trying to execute
TextMessage socketMessage = new TextMessage(message);
session.sendMessage(socketMessage);
}
So each thread is trying to send messages using same session Object..But am facing the following error
java.lang.IllegalStateException: Blocking message pending 10000 for BLOCKING
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.lockMsg(WebSocketRemoteEndpoint.java:130) ~[websocket-common-9.3.8.v20160314.jar:9.3.8.v20160314]
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.sendString(WebSocketRemoteEndpoint.java:379) ~[websocket-common-9.3.8.v20160314.jar:9.3.8.v20160314]
at org.springframework.web.socket.adapter.jetty.JettyWebSocketSession.sendTextMessage(JettyWebSocketSession.java:188) ~[spring-websocket-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:105) ~[spring-websocket-4.2.4.RELEASE.jar:4.2.4.RELEASE]
So is it possible to send asynchronous messages using spring websockets?
If yes please let me know what configuration changes are required in the above code..Or Can we extract the core AsyncRemoteEndPoint and BasicRemoteEndpoint from spring Websocket Session and can we send asynchronous messages..or if not both the above cases ..move the code to common place and put synchonized(sessionObject)
{
sendmessage
}..Sorry if the framing of question is not clear or already a duplicate question
Please note I am not using any Stomp client or anyother features over spring websocket..Am using plain spring websockets..And is it possible to do without using Future(java feature)(If yes..it would be better)?
I used ConcurrentWebSocketSessionDecorator on the session.
according to:
https://jira.spring.io/browse/SPR-13602
The decorator "enforces sending messages one at a time with a send buffer and send time limit per session. That helps quite a bit to limit the impact of slow clients"

Spring websocket & binaryjs

I use Spring 4.2.3 via spring-boot (1.3.0) at server and binaryjs 0.2.1 at client.
Binaryjs successfully send data over websocket to server, but i can't receive it (bytes).
How to declare method, that will be receive byte[] from websocket (and save, e.g. into temporary file)?
Spring websocket config:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/test");
}
}
I do not use withSockJS because SockJS can't send bytearray data
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/test").withSockJS();
}

Categories

Resources