宜城网站建设哪家好,网站备案登记,四川今天刚刚发生的新闻,企业推广宣传方案在公司中准备用websocker统计在线人数#xff0c;在WebSocketServer使用StringRedisTemplate保存数据到redis中去#xff0c;但是在保存的时候显示 StringRedisTemplate变量为null 详细问题
2023-08-20 10:37:14.109 ERROR 28240 --- [nio-7125-exec-1] o.a.t.websocket.po…在公司中准备用websocker统计在线人数在WebSocketServer使用StringRedisTemplate保存数据到redis中去但是在保存的时候显示 StringRedisTemplate变量为null 详细问题
2023-08-20 10:37:14.109 ERROR 28240 --- [nio-7125-exec-1] o.a.t.websocket.pojo.PojoEndpointBase : Failed to call onClose method of POJO end point for POJO of type [com.example.pipayshopapi.component.WebSocketServer]java.lang.reflect.InvocationTargetException: nullat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_382]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_382]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_382]at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_382]at org.apache.tomcat.websocket.pojo.PojoEndpointBase.onClose(PojoEndpointBase.java:103) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.WsSession.fireEndpointOnClose(WsSession.java:556) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:502) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:460) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.WsSession.close(WsSession.java:447) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.WsSession.close(WsSession.java:441) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.pojo.PojoEndpointBase.handleOnOpenOrCloseError(PojoEndpointBase.java:92) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:77) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:64) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:135) [tomcat-embed-websocket-9.0.41.jar:9.0.41]at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935) [tomcat-embed-core-9.0.41.jar:9.0.41]at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) [tomcat-embed-core-9.0.41.jar:9.0.41]at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.41.jar:9.0.41]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_382]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_382]at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.41.jar:9.0.41]at java.lang.Thread.run(Thread.java:750) [na:1.8.0_382]
Caused by: java.lang.NullPointerException: nullat com.example.pipayshopapi.component.WebSocketServer.onClose(WebSocketServer.java:70) ~[classes/:na]... 21 common frames omitted2023-08-20 10:37:14.109 ERROR 28240 --- [nio-7125-exec-1] c.e.p.component.WebSocketServer : 发生错误
java.lang.NullPointerExceptionat com.example.pipayshopapi.component.WebSocketServer.onOpen(WebSocketServer.java:56)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:65)at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:64)at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:135)at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935)at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:750)
java.lang.reflect.InvocationTargetExceptionat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.apache.tomcat.websocket.pojo.PojoEndpointBase.onClose(PojoEndpointBase.java:103)at org.apache.tomcat.websocket.WsSession.fireEndpointOnClose(WsSession.java:556)at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:502)at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:460)at org.apache.tomcat.websocket.WsSession.close(WsSession.java:447)at org.apache.tomcat.websocket.WsSession.close(WsSession.java:441)at org.apache.tomcat.websocket.pojo.PojoEndpointBase.handleOnOpenOrCloseError(PojoEndpointBase.java:92)at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:77)at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:64)at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:135)at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935)at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.NullPointerExceptionat com.example.pipayshopapi.component.WebSocketServer.onClose(WebSocketServer.java:70)... 21 more最后在网上搜索之后得出答案
因为spring对象的创建都是以单例模式创建的但是每一个用户连接websocker都会创建一次webscket对象所以当你启动项目时你想要注入的对象已经注入进去但是当用户连接是新创建的websocket对象没有你要注入的对象所以会报NullPointerException。
总结spring管理的都是单例singleton和 websocket 多对象相冲突. 解决方法
在WebSocketServer中使用set方法传入上下文 private static StringRedisTemplate stringRedisTemplate;Autowiredpublic void setChatService(StringRedisTemplate stringRedisTemplate) {WebSocketServer.stringRedisTemplate stringRedisTemplate;} 完整代码
import com.example.pipayshopapi.service.UserInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** author websocket服务*/Component
ServerEndpoint(value /dailyActive/{userId})
public class WebSocketServer {private static final Logger log LoggerFactory.getLogger(WebSocketServer.class);// 注入查看聊天列表的服务/*** 记录当前在线连接数*/public static final MapString, Session dailyActiveCount new ConcurrentHashMap();public static final String dailyActiveNamedailyActiveName;private RedisHandler redisHandlerRedisHandler.getInstance();private static StringRedisTemplate stringRedisTemplate;Autowiredpublic void setChatService(StringRedisTemplate stringRedisTemplate) {WebSocketServer.stringRedisTemplate stringRedisTemplate;}/*** 连接建立成功调用的方法*/OnOpenpublic void onOpen(Session session, PathParam(userId) String userId) {log.error(userId----------------------------------------------进入);// 保存当前用户sessiondailyActiveCount.put(userId, session);// 存入redis中去
// redisHandler.savedailyActive(dailyActiveName,dailyActiveCount.size());stringRedisTemplate.opsForValue().set(dailyActiveName,String.valueOf(dailyActiveCount.size()));}/*** 连接关闭调用的方法*/OnClosepublic void onClose(Session session, PathParam(userId) String userId) {log.error(userId----------------------------------------------关闭);// 移除当前用户sessiondailyActiveCount.remove(userId);// 存入redis中去
// redisHandler.savedailyActive(dailyActiveName,dailyActiveCount.size());stringRedisTemplate.opsForValue().set(dailyActiveName,String.valueOf(dailyActiveCount.size()));}/*** 收到客户端消息后调用的方法* 后台收到客户端发送过来的消息* onMessage 是一个消息的中转站* 接受 浏览器端 socket.send 发送过来的 json数据*/OnMessagepublic void onMessage(Session session, String message,PathParam(userId) String userId) {}OnErrorpublic void onError(Session session, Throwable error) {log.error(发生错误);error.printStackTrace();}}