Springboot-WebSocket获取HttpSession问题
换了新工作,第一个任务就是和这个有关,以前没接触过,没办法,各种度娘、谷哥,大部分都是只言片语,要么就是特定的配置环境还不贴配置……,踩坑无数, 遂整理成笔记
WebSocket协议
WebSocket是一种在单个TCP连接上进行全双工通讯的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
STOMP协议
STOMP是面向文本的消息传送协议。STOMP客户端与支持STOMP协议的消息代理进行通信。STOMP使用不同的命令,如连接,发送,订阅,断开等进行通信。
具体参考:官方介绍
SockJS
SockJS是一个JavaScript库,提供跨浏览器JavaScript的API,创建了一个低延迟、全双工的浏览器和web服务器之间通信通道
以上内容出自维基百科和百度百科
环境配置
- SpringBoot2.0全家桶
- 特别说明一下,现在很多服务器都支持websocket,我这次写代码用的是SpringBoot内置的tomcat
应用场景
- 如果只是单纯的配置一个建立连接发送消息,并不难,具体客户端编写参考这个 菜鸟教程-websocket
- 我需要解决的问题是:当客户端和服务器建立连接时,将登录的用户信息从httpSession中取出,这个问题的难点在于,websocket的请求和http请求完全不相关,所以没有办法直接获取HttpSession
实施思路
- 服务器端的编码实现,具体有两套方案
- 使用继承的方式,这种方式,我在看Spring官方介绍文档时貌似也是这种方式实现的
- 使用注解的方式:很蛋疼的是我们的项目使用的是这种方式
- 具体思路
- 虽然websocket的请求和http请求完全不相关,但是如果基于注解的话,EndPoint支持读取一个配置
- 我当时的想法就是在配置中拦截或者获取HttpSession,事实证明思路是正确的,但是当我按照这个思路去百度谷歌发现获取的一律都是null,然后我就崩溃了
具体编码实现
只贴核心代码,完整项目在本文的底部,我放在了github上
先上核心的服务器端消息处理类
/**
* WebSocket主要的消息类
* @author 侯叶飞
*/
//onfigurator = WebsocketConfig.class 该属性就是我上面提到我们可以自己配置的东西
@ServerEndpoint(value = "/api/websocket", configurator = WebsocketConfig.class)
@Component
@Slf4j
public class WebSocket {
/*每个浏览器连接都会有一个新的会话对象*/
private Session session;
/*用来存储每个会话的session,静态的不会被实例化*/
private static CopyOnWriteArraySet<WebSocket> webSocketSets = new CopyOnWriteArraySet<>();
/**
* 主要用来监听连接建立,config用来获取WebsocketConfig中的配置信息
* @param session
* @param config
*/
@OnOpen
public void onOpen(Session session, EndpointConfig config) {
log.info("config:{}", config.getUserProperties().get("name"));
log.info("session:{}", config.getUserProperties().get("sessionid"));
this.session = session;
webSocketSets.add(this);
log.info("【websocket消息】有新的连接, 总数:{}", webSocketSets.size());
} @OnClose
public void onClose() {
webSocketSets.remove(this);
log.info("【websocket消息】连接断开, 总数:{}", webSocketSets.size());
} @OnError
public void onError(Throwable e, Session session) {
webSocketSets.remove(this);
log.info("【websocket消息】连接出错或未关闭socket:" + e.getMessage()); } @OnMessage
public void onMessage(String message, Session session) {
for(WebSocket ws:webSocketSets){
ws.session.getAsyncRemote().sendText("广播:"+message);
}
log.info("【websocket消息】收到客户端发来的消息:{}", message);
}
}下面代码就是核心的配置类
/**
* 主要的配置类
* 本类必须要继承Configurator,因为@ServerEndpoint注解中的config属性只接收这个类型
* @author 侯叶飞
*
*/
@Configuration
@Slf4j
public class WebsocketConfig extends ServerEndpointConfig.Configurator { private static final String HttpSession = null;
/* 修改握手,就是在握手协议建立之前修改其中携带的内容 */
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
/*如果没有监听器,那么这里获取到的HttpSession是null*/
StandardSessionFacade ssf = (StandardSessionFacade) request.getHttpSession();
if (ssf != null) {
HttpSession session = (HttpSession) request.getHttpSession();
sec.getUserProperties().put("sessionid", session);
log.info("获取到的SessionID:{}",session.getId());
}
sec.getUserProperties().put("name", "小强");
super.modifyHandshake(sec, request, response);
}
@Bean
public ServerEndpointExporter serverEndpointExporter() {
//这个对象说一下,貌似只有服务器是tomcat的时候才需要配置,具体我没有研究
return new ServerEndpointExporter();
}
}
- 仅仅有上面的配置获取的肯定是null,至于原因,网上说法不一,我也不确定,解决方案如下
/**
* 监听器类:主要任务是用ServletRequest将我们的HttpSession携带过去
* @author 侯叶飞
*/
@Component //此注解千万千万不要忘记,它的主要作用就是将这个监听器纳入到Spring容器中进行管理,相当于注册监听吧
@Slf4j
public class RequestListener implements ServletRequestListener {
@Override
public void requestInitialized(ServletRequestEvent sre) {
//将所有request请求都携带上httpSession
HttpSession session = ((HttpServletRequest) sre.getServletRequest()).getSession();
log.info("将所有request请求都携带上httpSession {}",session.getId());
}
public RequestListener() {} @Override
public void requestDestroyed(ServletRequestEvent arg0) {}
}
此外在我谷歌的过程中有博客提到需要添加一个WebListener的注解,结果发现基于springboot的话,如果不加也不影响
GitHub项目地址:Demo
以上代码纯属个人研究,如果有错误的地方,各位留言或者发邮件都可以!
Springboot-WebSocket获取HttpSession问题的更多相关文章
- WebSocket获取httpSession空指针异常的解决办法
小坑:使用requestListner解决不了这个问题! 如何获取HttpSession 在使用webSocket实现p2p或者一对多聊天功能的时候我们经常会有这样的需求:webSocket服务端需要 ...
- java使用Websocket获取HttpSession出现的问题与解决
websocket的写法就不多说了,主要记一记其中出现的问题 1.获取不到httpSession 解决办法:先重写握手方法,将httpsession放入ServerEndpointConfig.get ...
- java使用websocket,并且获取HttpSession,源码分析
转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...
- WebSocket之获取HttpSession
WebSocket之获取HttpSession 由于WebSocket与Http协议的不同,故在使用常用的HttpSession方面就存在了一些问题.通过google翻阅到了在onOpen方法下使用H ...
- Springboot+Websocket+JWT实现的即时通讯模块
场景 目前做了一个接口:邀请用户成为某课程的管理员,于是我感觉有能在用户被邀请之后能有个立马通知他本人的机(类似微博.朋友圈被点赞后就有立马能收到通知一样),于是就闲来没事搞了一套. 涉及技术栈 ...
- Netty+WebSocket 获取火币交易所数据项目
Netty+WebSocket 获取火币交易所时时数据项目 先附上项目项目GitHub地址 spring-boot-netty-websocket-huobi 项目简介 本项目使用 SpringBoo ...
- webSocket 使用 HttpSession 的数据配置与写法
1.前言 webSoket 无法获取 HttpSession ,使用就更谈不上了 !!! 2解决过程 使用 configurator 注入即可 (1) 配置一个类 1 package cn.c ...
- SpringBoot+WebSocket
SpringBoot+WebSocket 只需三个步骤 导入依赖 <dependency> <groupId>org.springframework.boot</grou ...
- springboot+websocket+sockjs进行消息推送【基于STOMP协议】
springboot+websocket+sockjs进行消息推送[基于STOMP协议] WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就 ...
随机推荐
- Sqli labs系列-less-1 详细篇
要说 SQL 注入学习,网上众多的靶场,就属 Sqli labs 这个系列挺不错的,关卡达到60多关了,我自己也就打了不几关,一个挺不错的练习SQL注入的源码. 我一开始就准备等我一些原理篇总结完了, ...
- C++语言编程基础
C++程序设计语言可以看作C语言的改进和升级,不仅完全兼容了C语言的语法和函数库,还引入了面向对象.运算符重载.多态性.数据流和模板等最新的编程思想.极大地保证了源代码的生产率.质量和可重用性.GNU ...
- Mysql数据库命令行输入错误怎么办
Mysql数据库命令行输入错误 缺少另一半 错误输入 ' 或 " 时,必须键入另一半才能退出命令. 缺少分号 写入语句缺少分号需要补全. 输入quit或者exit退出 ctrl+c,完全退出 ...
- 用 Flask 来写个轻博客 (1) — 创建项目
目录 目录 前言 扩展阅读 部署开发环境 创建 Github 项目 前言 一步一步的实现一个 Flask 轻博客项目启动,最新的代码会上传到 Github. 扩展阅读 欢迎使用 Flask - vir ...
- 19、Linux命令对服务器内存进行监控
国际惯例,我们要知道什么是服务器的内存,内存有哪些作用.这里就不做过多介绍,Linux性能监控需要我们对底层要有一定的理解.下面我将会列出我常用的监控内存的工具. vmstat vmstat显示关于进 ...
- CSP2019总结
CSP2019总结 前言 赛前停课集训了两个星期,自认为已经准备充分了,结果... 不知道有没有写挂分,即使一分没挂,满打满算也只有400出头,还是太菜了. Day0 晚上复习了一会,打了会游戏就睡了 ...
- 2017 ICPC Asia Urumqi A.coins (概率DP + 期望)
题目链接:Coins Description Alice and Bob are playing a simple game. They line up a row of nn identical c ...
- springboot1.5.x升级到2.1.x切换分支导致的maven依赖混乱
背景:项目springboot版本由1.5.X升级到2.1.X,两个版本的分支需要共存,来回切换的时候,maven依赖各种报红 查看dependency发现1.5.X的jar和2.1.X的jar都存在 ...
- 冲上云霄,Dubbo Go!
来源:开源中国社区 5 月 21 日,经过一年多的孵化,Apache Dubbo 从 Apache 软件基金会毕业,成为 Apache 顶级项目.推荐:厉害了,Dubbo 正式毕业! Dubbo 是阿 ...
- 【洛谷】P1229快速幂
题目链接:https://www.luogu.org/problemnew/show/P1226 题意:求b^p % m之后的结果 题解:快速幂模板 代码: #include<iostream& ...