当前位置: 首页 > news >正文

websocker无法注入依赖

在公司中准备用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 Map<String, Session> dailyActiveCount = new ConcurrentHashMap<>();public static final String dailyActiveName="dailyActiveName";private RedisHandler redisHandler=RedisHandler.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();}}

 

http://www.lryc.cn/news/133643.html

相关文章:

  • 如何进行无线网络渗透测试?
  • 【Python机器学习】实验15 将Lenet5应用于Cifar10数据集(PyTorch实现)
  • Jeep车型数据源:提供Jeep品牌车系、车型、价格、配置等信息
  • clickhouse-备份恢复
  • (2018,ProGAN)渐进式发展 GAN 以提高质量、稳定性和变化
  • 负载均衡下的 WebShell 连接
  • Postman的高级用法—Runner的使用​
  • spring如何进行依赖注入,通过set方法把Dao注入到serves
  • Python使用图像处理库PIL(Python Imaging Library)和NumPy库来比较两副图像的相似度
  • clickhouse扩缩容
  • 动漫3D虚拟人物制作为企业数字化转型提供强大动力
  • 数据同步工具比较:选择适合您业务需求的解决方案
  • Python中数据结构列表详解
  • 引领行业高质量发展|云畅科技参编《低代码开发平台创新发展路线图(2023)》
  • Ubuntu22.04编译Nginx源码
  • 视频上传,限制时长,获取视频时长
  • Open3D 进阶(5)变分贝叶斯高斯混合点云聚类
  • 5、css学习5(链接、列表)
  • Synchronized与Java线程的关系
  • 使用本地电脑搭建可以远程访问的SFTP服务器
  • 批量修改文件名怎么操作?
  • 【LeetCode】538.把二叉搜索树转换为累加树
  • linux 安装 kibana
  • STM32入门——IIC通讯
  • DTC 19服务学习2
  • 【腾讯云 TDSQL-C Serverless 产品体验】基于腾讯云轻量服务器以及 TDSQL-C 搭建 LNMP WordPress 博客系统
  • 【vue3】对axios进行封装,方便更改路由并且可以改成局域网ip访问(附代码)
  • Java IO流(三)线程模型
  • string(模拟实现与深拷贝)
  • 5.Vue_Element