基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【九】【整合websocket】
来源:互联网 发布:在ubuntu安装anaconda 编辑:程序博客网 时间:2024/06/07 04:43
细心的朋友一定在上一章节的程序运行中发现了这样的一个报错:
这个报错的造成是因为在大家访问首页的时候,我前端开启了websocket的连接,但是我们的后端并没有对websocket进行相应的支持,因此本章将教大家如何开启对websocket的支持。
对于websocket的maven依赖已经在本工程中引入了因此此处就不在叙述了,在我们的sys的config包底下新建websocket文件夹如下所示:
接着我们增加websocket的配置文件分别是:InMessage.java(消息接收实体)、OutMessage.java(消息发送实体)、SocketSessionRegistry.java(用户session记录)、STOMPConnectEventListener.java(监听类)、WebSocketConfig.java(配置类)代码如下:
/** * 消息接收实体 */public class InMessage { private String name; private String id; public InMessage() { } public InMessage(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; }}
/** * 消息推送实体 */public class OutMessage { private String content; public OutMessage() { } public OutMessage(String content) { this.content = content; } public String getContent() { return content; }}
/** * Created by baiguantao on 2017/8/4. * 用户session记录类 */public class SocketSessionRegistry{ //this map save every session //这个集合存储session private final ConcurrentMap<String, Set<String>> userSessionIds = new ConcurrentHashMap(); private final Object lock = new Object(); public SocketSessionRegistry() { } /** * * 获取sessionId * @param user * @return */ public Set<String> getSessionIds(String user) { Set set = (Set)this.userSessionIds.get(user); return set != null?set: Collections.emptySet(); } /** * 获取所有session * @return */ public ConcurrentMap<String, Set<String>> getAllSessionIds() { return this.userSessionIds; } /** * register session * @param user * @param sessionId */ public void registerSessionId(String user, String sessionId) { Assert.notNull(user, "User must not be null"); Assert.notNull(sessionId, "Session ID must not be null"); Object var3 = this.lock; synchronized(this.lock) { Object set = (Set)this.userSessionIds.get(user); if(set == null) { set = new CopyOnWriteArraySet(); this.userSessionIds.put(user, (Set<String>) set); } // 当最迟登陆的时间和当前时间的年月日不匹配的时候清空session缓存 User userLogin = UserInfo.getUser(); if(userLogin!=null){ if(!DateUtil.format(userLogin.getLastLoginDate(), DatePattern.NORM_DATE_FORMAT).equalsIgnoreCase(DateUtil.format(new Date(), DatePattern.NORM_DATE_FORMAT))){ set = new CopyOnWriteArraySet(); this.userSessionIds.put(user, (Set<String>) set); } } ((Set)set).add(sessionId); } } public void unregisterSessionId(String userName, String sessionId) { Assert.notNull(userName, "User Name must not be null"); Assert.notNull(sessionId, "Session ID must not be null"); Object var3 = this.lock; synchronized(this.lock) { Set set = (Set)this.userSessionIds.get(userName); if(set != null && set.remove(sessionId) && set.isEmpty()) { this.userSessionIds.remove(userName); } } }}
/** * Created by baiguantao on 2017/8/4. * STOMP监听类 * 用于session注册 以及key值获取 */public class STOMPConnectEventListener implements ApplicationListener<SessionConnectEvent> { @Autowired SocketSessionRegistry webAgentSessionRegistry; @Override public void onApplicationEvent(SessionConnectEvent event) { StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage()); //login get from browser String agentId = sha.getNativeHeader("login").get(0); String sessionId = sha.getSessionId(); System.out.println("接收的sessionId是:"+sessionId); webAgentSessionRegistry.registerSessionId(agentId,sessionId); }}
/** 类描述:* @auther linzf* @create 2017/8/8 0008 */@Configuration@EnableWebSocketMessageBrokerpublic class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic");// /users 默认通知 config.setApplicationDestinationPrefixes("/app"); //设置前缀 默认是user 可以修改 点对点时使用 config.setUserDestinationPrefix("/ricky/"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ricky-websocket").withSockJS(); } @Bean public SocketSessionRegistry SocketSessionRegistry(){ return new SocketSessionRegistry(); } @Bean public STOMPConnectEventListener STOMPConnectEventListener(){ return new STOMPConnectEventListener(); }}
接着我们重新加载我们的代码,并运行我们的项目,当我们登陆成功以后我们会看到以下的截图说明我们的websocket已经配置成功了:
那么我们该如何运用我们的websocket呢,假设我们这里模拟这样的一个场景:用户在手机端下了一个订单,那么后台登陆的当前商户需要收到这个订单的信息那么我们来模拟实现这么一个场景。
首先我们在sys的controller包底下创建一个类WebsocketController.java内容如下:
/** 类描述:* @auther linzf* @create 2017/12/11 0011 */@Controller@RequestMapping("/websocket")public class WebsocketController { /**session操作类*/ @Autowired private SocketSessionRegistry webAgentSessionRegistry; /**消息发送工具*/ @Autowired private SimpMessagingTemplate template; /** * 功能描述:给全局推送消息 */ @RequestMapping(value = "/sendAll",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public void sendAll(){ Map<String,Set<String>> all = webAgentSessionRegistry.getAllSessionIds(); JSONObject jobj = new JSONObject(); jobj.put("test","test"); all.forEach((k,v)->{ v.forEach(x->{ template.convertAndSendToUser(x,"/topic/greetings",new OutMessage(jobj.toString()),createHeaders(x)); }); }); } /** * 功能描述:给指定账号推送消息 */ @RequestMapping(value = "/sendUser",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public void senduUser(){ // 此处账号已经被写死为hyll 大家可以根据自己的实际业务来修改此处的代码 Set<String> keys = webAgentSessionRegistry.getSessionIds("hyll"); JSONObject jobj = new JSONObject(); jobj.put("hyll","hyll"); keys.forEach(x->{ template.convertAndSendToUser(x,"/topic/greetings",new OutMessage(jobj.toString()),createHeaders(x)); }); } /** * 功能描述:组装JSON数据的头部数据 * @param sessionId * @return */ private MessageHeaders createHeaders(String sessionId) { SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE); headerAccessor.setSessionId(sessionId); headerAccessor.setLeaveMutable(true); return headerAccessor.getMessageHeaders(); }}
我们重新加载我们的代码并运行我们的程序然后登陆我们的首页,接着分别调用以上的两个接口(http://127.0.0.1:8080/websocket/sendAll 、http://127.0.0.1:8080/websocket/sendUser):我们可以看到结果如下:
这两个就是从后端推送到页面的信息,该块的js逻辑大家可以在main.html页面找到,大家根据自己的实际业务来扩展该块的内容如下:
到此处我们已经整合好了我们的websocket的代码,整个代码的GitHub地址是:https://github.com/185594-5-27/csdndemo/tree/master-websocket
上一篇文章地址:基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【八】【完善整个项目】
下一篇文章地址:正在编写中
QQ交流群:578746866
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【九】【整合websocket】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【三】【整合swagger2和druid】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【六】【引入bootstrap前端框架】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【一】【构建工程】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【四】【编写基础开发工具】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【七】【菜单维护模块】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【八】【完善整个项目】
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【五】【编写基础代码快速生成工具】
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- springmvc整合redis架构搭建
- springBoot整合webSocket
- SpringBoot整合WebSocket案例
- 基于 SpringBoot 和 webSocket 的匿名聊天室
- 值得学习的C/C++资源(转)
- iOS 高级研发
- CentOS6.5在VMware10中安装
- 主题:关于在linux中无法启动MySQL的问题.
- 电商RadioButton 底部点击按钮
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【九】【整合websocket】
- 安装API网关kong遇到的一些坑及解决办法
- 解决关于iis 中使用 word COM+ 组件的问题 ,应该基本上 都是 权限授权的问题
- ios音乐播放器-仿QQ音乐
- pyspark之DataFrame学习(1)
- css--图片处理
- 手摸手教你在vue-cli里面使用vuex,以及vuex简介
- Zuul超时问题,微服务响应超时,zuul进行熔断
- 上传文件测试用例