grails springboot_Springboot 集成 Websocket (with Shiro)

目前 打算给我的ECS服务器做一个状态监控

前端准备使用Echarts做图表 服务器信息通过云服务器 ECS API 获取,然后再自己加一些信息 然后通过websocket 发送状态数据

Echarts 已经比较熟悉了,有再项目中使用过 Websocket 也有在项目中使用过,不过是在

进入正题

Springboot 配置 Websocket

网上大量文章都是在使用过时的配置方式

springboot 已经帮助我们做了很多配置 推荐优先查看官方文档

我的Springboot版本为2.1.4.RELEASE

第一步 添加依赖

pom.xml

//others dependency

org.springframework.boot

spring-boot-starter-websocket

第二步 创建接收前端消息类

WebsocketMessage.groovy ps:一定需要set/get方法

class WebsocketMessage {

/** 我使用的是Groovy* 也可以定义 String data* 消息内容*/

def data

/** 发送的目的地 */

String destination

def getData() {

return data

}

void setData(data) {

this.data = data

}

String getDestination() {

return destination

}

void setDestination(String destination) {

this.destination = destination

}

}

第三步 创建Websocket控制器

MonitorController.groovy

@Controller

class MonitorController {

@MessageMapping("/hello") //响应前端发送"/app/hello"地址 @SendTo("/topic/helloEcho") // 告诉springboot将方法返回值通过websocket发送到 "/topic/helloEcho"地址 public ResponseData helloEcho(WebsocketMessage message) throws Exception {

/** 我这里是返回了自定义的响应对象,并放入了用户发送来的消息 */

return new ResponseData(data: "echo:${message.getData()}")

}

}

第四步 创建Websocket 配置类

WebSocketConfig.java特别注意

registry.addEndpoint("/hoody-websocket").setAllowedOrigins("*").withSockJS();

开发环境我使用了通配符, 正式环境应该传入 允许的源 可以通过profile控制

@Configuration

@EnableWebSocketMessageBroker

public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

/** 允许使用topic,并且所有主题地址前缀为"/app" */

@Override

public void configureMessageBroker(MessageBrokerRegistry config) {

config.enableSimpleBroker("/topic");

config.setApplicationDestinationPrefixes("/app");

}

/*** 添加一个/hoody-websocket端点,客户端就可以通过这个端点来进行连接;* withSockJS作用是添加SockJS支持,* setAllowedOrigins(String... var1) 指定可以跨域访问的地址*/

@Override

public void registerStompEndpoints(StompEndpointRegistry registry) {

registry.addEndpoint("/hoody-websocket").setAllowedOrigins("*").withSockJS();

}

}

第五步 前端Vue 使用 Stomp 和 SockJS 访问

import Stomp from 'stompjs'

import SockJS from 'sockjs-client'

export default {

name: 'websocket',

data() {

return {

stompClient: null,

timer: null,

}

},

mounted() {

this.initWebSocket()

},

beforeDestroy: function() {

/** 页面离开时断开连接,清除定时器 */

this.disconnect()

clearInterval(this.timer)

},

methods: {

/** 绑定 按钮发送 */

clickBtn() {

this.sendWsMessage("Hi,world")

},

sendWsMessage(msg) {

/** 向'/app/hello' 发送 消息,需要将对象转换为JSON 字符串this.stompClient.send('/app/hello', {},JSON.stringify({ data: msg }),)},/** 收到消息处理 */

onMessage(msg) {

this.$message.success('收到消息:' + msg) // msg.body存放的是服务端发送给我们的信息 },

/** 初始化Socket连接 */

initWebSocket() {

this.connection()

const that = this

// 断开重连机制,尝试发送消息,捕获异常发生时重连 10秒一次 this.timer = setInterval(() => {

try {

that.stompClient.send('test')

} catch (err) {

that.$message.warning('断线了: ' + err)

that.connection()

}

}, 10000)

},

connection() {

// 建立连接对象 const socket = new SockJS('/api/hoody-websocket')

// 获取STOMP子协议的客户端对象 this.stompClient = Stomp.over(socket)

// 定义客户端的认证信息,按需求配置 // 向服务器发起websocket连接 const that = this

this.stompClient.connect({ 'X-Token': that.$store.getters.token }, () => {

this.stompClient.subscribe('/topic/helloEcho', (msg) => { // 订阅服务端提供的某个topic that.onMessage(msg.body)

msg.ack()

})

// 用户加入接口 }, (err) => {

// 连接发生错误时的处理函数 that.$message.error(err)

})

}, // 连接 后台 disconnect() {

if (this.stompClient) {

this.stompClient.disconnect()

}

} // 断开连接 }

}

现在可以愉快的访问了

第七步 了解shiro-spring-boot-web-starter 帮我们做了的事

在浏览器开发者工具 的Console 可以看到连接成功的信息

>>> CONNECT

X-Token:4dead694-eb84-496f-ba93-802b6fcbe939

accept-version:1.1,1.0

heart-beat:10000,10000

------------------------------------------------------

<<< CONNECTED

version:1.1

heart-beat:0,0

user-name:User{id=34, username='111',password='dab73e9a6c79ec96117d1474f68f2249'}

------------------------------------------------------

connected to server

------------------------------------------------------

>>> SUBSCRIBE

id:sub-0

destination:/topic/helloEcho

连接成功信息,居然从服务器返回了当前登录用户的账号信息,但是为什么会把密码也搞过来啊 这个信息看起来很像我的User.toString() ~~还好我没把盐值也发出来~~ 于是打了断点看了一下流程

1. 服务器收到 ws://localhost/hoody-websocket/ 连接后将会执行getName()方法 org.springframework.web.servlet.FrameworkServlet

protected String getUsernameForRequest(HttpServletRequest request) {

Principal userPrincipal = request.getUserPrincipal();

return (userPrincipal != null ? userPrincipal.getName() : null);

}

2.如果你的用户类没有getName()方法 他就会!!! 获取 整个对象的toString() ShiroHttpServletRequest

public String getName() {

return getObject().toString();

}

所以,检查你的User类,不要把密码也搞出去了,就算是加密的也不要

原文发布与我的个人博客Springboot 接入Websocket (with Shiro)​hoody.tech

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值