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();}}
相关文章:
websocker无法注入依赖
在公司中准备用websocker统计在线人数,在WebSocketServer使用StringRedisTemplate保存数据到redis中去,但是在保存的时候显示 StringRedisTemplate变量为null 详细问题 2023-08-20 10:37:14.109 ERROR 28240 --- [nio-7125-exec-1] o.a.t.websocket.po…...
如何进行无线网络渗透测试?
我们将重点介绍如何使用Kali Linux进行无线网络渗透测试。无线网络渗透测试是评估无线网络安全性的重要步骤,而Kali Linux作为一款专业的渗透测试发行版,提供了丰富的工具来进行这项任务。 1. 准备工作 在开始无线网络渗透测试之前,有一些准…...
【Python机器学习】实验15 将Lenet5应用于Cifar10数据集(PyTorch实现)
文章目录 CIFAR10数据集介绍1. 数据的下载2.修改模型与前面的参数设置保持一致3. 新建模型4. 从数据集中分批量读取数据5. 定义损失函数6. 定义优化器7. 开始训练8.测试模型 9. 手写体图片的可视化10. 多幅图片的可视化 思考题11. 读取测试集的图片预测值(神经网络的…...
Jeep车型数据源:提供Jeep品牌车系、车型、价格、配置等信息
Jeep是一个极具特色的汽车品牌,它的所有车型都注重实用性,具有越野性能和高性能。Jeep品牌在汽车行业中的口碑一直是非常不错的。如果你想要了解Jeep品牌车系、车型、价格、配置等信息,就可以通过挖数据平台Jeep车型数据源API接口…...
clickhouse-备份恢复
一、简介 备份恢复是数据库常用的手段,可能大多数公司很少会对大数据所使用的数据进行备份,这里还是了解下比较好,下面做了一些简单的介绍,详细情况可以通过官网来查看,经过测试发现Disk中增量备份并不好用࿰…...
(2018,ProGAN)渐进式发展 GAN 以提高质量、稳定性和变化
Progressive Growing of GANs for Improved Quality, Stability, and Variation 公众号:EDPJ 目录 0. 摘要 1. 简介 2. GAN 的渐进式发展 3. 使用小批量标准差增加变化 4. 生成器和判别器的归一化 4.1 均衡学习率 4.2 生成器中的像素特征向量归一化 5. 评…...
负载均衡下的 WebShell 连接
目录 负载均衡简介负载均衡的分类网络通信分类 负载均衡下的 WebShell 连接场景描述难点介绍解决方法**Plan A** **关掉其中一台机器**(作死)**Plan B** **执行前先判断要不要执行****Plan C** 在Web 层做一次 HTTP 流量转发 (重点࿰…...
Postman的高级用法—Runner的使用
1.首先在postman新建要批量运行的接口文件夹,新建一个接口,并设置好全局变量。 2.然后在Test里面设置好要断言的方法 如: tests["Status code is 200"] responseCode.code 200; tests["Response time is less than 10000…...
spring如何进行依赖注入,通过set方法把Dao注入到serves
1、选择Generate右键鼠标 你在service层后面方法的这些: 2、UserService配置文件的写法是怎样的: 3、我们在UserController中执行一下具体写法: 最后我们执行一下 : 4、这里可能出现空指针,因为你当前web层,因为你new这个对象根…...
Python使用图像处理库PIL(Python Imaging Library)和NumPy库来比较两副图像的相似度
目录 1、解释说明: 2、使用示例: 3、注意事项: 1、解释说明: 在Python中,我们可以使用图像处理库PIL(Python Imaging Library)和NumPy库来比较两副图像的相似度。常用的图像相似度计算方法有…...
clickhouse扩缩容
一、背景 我们之前已经学会了搭建clickhouse集群,我们搭建的是一套单分片两副本的集群,接下来我们来测试下clickhouse的扩缩容情况 二、扩容 扩容相对来说比较简单,我们原来的架构如下 hostshardreplica192.169.1.111192.169.1.212 现在…...
动漫3D虚拟人物制作为企业数字化转型提供强大动力
一个 3D 虚拟数字人角色的制作流程,可以分为概念设定-3D 建模-贴图-蒙皮-动画-引擎测试六个步骤,涉及到的岗位有原画师、模型师、动画师等。角色概念设定、贴图绘制一般是由视觉设计师来完成;而建模、装配(骨骼绑定)、渲染动画是由三维设计师来制作完成。…...
数据同步工具比较:选择适合您业务需求的解决方案
在当今数字化时代,数据已经成为企业的核心资产。然而,随着业务的扩展和设备的增多,如何实现数据的高效管理和同步成为了一个亟待解决的问题。本文将介绍几种常见的数据同步工具,并对比它们的功能、性能和适用场景,帮助…...
Python中数据结构列表详解
列表是最常用的 Python 数据类型,它用一个方括号内的逗号分隔值出现,列表的数据项不需要具有相同的类型。 列表中的每个值都有对应的位置值,称之为索引,第一个索引是 0,第二个索引是 1,依此类推。列表都可…...
引领行业高质量发展|云畅科技参编《低代码开发平台创新发展路线图(2023)》
8月8日-9日,中国电子技术标准化研究院于北京顺利召开《低代码开发平台创新发展路线图(2023)》封闭编制会。云畅科技、浪潮、百度、广域铭岛等来自低代码开发平台解决方案供应商、用户方、科研院所等近30家相关单位的40余位专家参与了现场编制…...
Ubuntu22.04编译Nginx源码
执行如下命令 # ./configure --sbin-path/usr/local/nginx/nginx --conf-path/usr/local/nginx/nginx.conf --pid-path/usr/local/nginx/nginx.pid输出结果,出现如下: Configuration summary using system PCRE2 library OpenSSL library is not used …...
视频上传,限制时长,获取视频时长
使用element的upload上传文件时,除了类型和大小,需求需要限制只能长传18秒内的视频,这里通过upload的before-upload,以及创建一个音频元素对象拿到durtaion时长属性来实现。 getVideoTime(file) {return new Promise(async (resol…...
Open3D 进阶(5)变分贝叶斯高斯混合点云聚类
目录 一、算法原理二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 系列文章(连载中。。。爬虫,你倒是爬个完整的呀?): Open3D 进阶(1) MeanShift点云聚类Open3D 进阶(2)DB…...
5、css学习5(链接、列表)
1、css可以设置链接的四种状态样式。 a:link - 正常,未访问过的链接a:visited - 用户已访问过的链接a:hover - 当用户鼠标放在链接上时a:active - 链接被点击的那一刻 2、 a:hover 必须在 a:link 和 a:visited 之后, a:active 必须在 a:hover 之后&…...
Synchronized与Java线程的关系
前言 Java多线程处理任务时,为了线程安全,通常会对共享资源进行加锁,拿到锁的线程才能进行访问共享资源。而加锁方式通过都是Synchronized锁或者Lock锁。 那么多线程在协同工作的时候,线程状态的变化都与锁对象有关系。 …...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
