I am creating a Handler that extends TextWebSocketHandler
and am able to print the data send from my client in Flutter.io
. However, when I try passing the data to a service I am getting a bunch of errors as seen below:
Closing session due to exception for StandardWebSocketSession[id=9eb9b6b1-2fab-b27d-9ca1-22815c957e68, uri=ws://localhost:8080/name]
java.lang.NullPointerException: null
at offtop.Config.SocketHandler.lambda$0(SocketHandler.java:41) ~[classes/:na]
at java.base/java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658) ~[na:na]
at offtop.Config.SocketHandler.handleTextMessage(SocketHandler.java:40) ~[classes/:na]
at org.springframework.web.socket.handler.AbstractWebSocketHandler.handleMessage(AbstractWebSocketHandler.java:43) ~[spring-websocket-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75) ~[spring-websocket-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleMessage(LoggingWebSocketHandlerDecorator.java:56) ~[spring-websocket-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleMessage(ExceptionWebSocketHandlerDecorator.java:58) ~[spring-websocket-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:114) ~[spring-websocket-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$000(StandardWebSocketHandlerAdapter.java:43) ~[spring-websocket-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:85) ~[spring-websocket-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:82) ~[spring-websocket-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:395) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:119) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:495) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:294) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:82) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148) ~[tomcat-embed-websocket-9.0.27.jar:9.0.27]
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.27.jar:9.0.27]
at java.base/java.lang.Thread.run(Thread.java:835) ~[na:na]
I first thought it was an issue with how I am calling my service, however, I am using @Autowired and also tried using ApplicationContext to configure my DI. Now I'm just not sure what the issue is. I would be using STOMP and SockJS Websocket configuration if Flutter.io provided support for that, now I am using these configurations and classes to handle incoming data with websockets.
Below is my code
WSConfig.java | How I configured my websocket
package offtop.Config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WSConfig implements WebSocketConfigurer{
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new SocketHandler(), "/name");
}
}
SocketHandler.java | How I am handling incoming data
package offtop.Config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Stream;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import offtop.Services.WebsocketService;
@Component
public class SocketHandler extends TextWebSocketHandler {
@Autowired
private WebsocketService websocketService;
List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message)
throws IOException {
for (int i = 0; i < sessions.size(); i++) {
WebSocketSession webSocketSession = (WebSocketSession) sessions.get(i);
Map value = new Gson().fromJson(message.getPayload(), Map.class);
System.out.println(value.toString());
Stream<String> s = Stream.of(value.values().toString());
s.forEach(val -> {
websocketService.logData(val);
});
webSocketSession.sendMessage(new TextMessage("Received " + value.get("message") + " !"));
}
}
@Override
public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
System.out.println("sessions: " + session.toString());
sessions.add(session);
}
}
WebsocketService.java | Service I am using to manipulate incoming data from websocket text
package offtop.Services;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Service;
@Service
@Configurable
public class WebsocketService{
public String logData(String val){
System.out.println("val incoming: " + val);
return "works";
}
}
Thank you in advance, and If am approaching this completely wrong please let me know.
The issue here is that it is not autowiring WebsocketService
into the SocketHandler
because you are using the new
operator in registerWebSocketHandlers()
. You need to autowire the socketHandler in WSConfig
and use the autowired instance.
As a general rule, you should never call new
on a Spring managed bean, autowire it instead.
You should generally not use @Service
and @Configurable
together, one is registering a Spring bean and the other is telling Spring that you will create your own instances. In this case you should use only @Service
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.