springboot+vue整合websocket(含鉴权)
springboot+vue+websocket 包含spring security鉴权
·
1、前端页面代码
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" label-width="100px">
<el-form-item label="类型" prop="type">
<el-select v-model="queryParams.type" clearable placeholder="请选择类型">
<el-option value="1" label="全服执行SQL"></el-option>
<el-option value="2" label="查看日志"></el-option>
</el-select>
</el-form-item>
<el-form-item label="SQL语句">
<el-input type="textarea" :rows="3"
v-model="queryParams.msg"
placeholder="请输入SQL语句"
clearable
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="submit">提 交</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getToken } from "@/utils/auth";
export default {
data(){
return{
// 此处为websocket地址, 8080是springboot监听的web端口
// /websocket/execute与controller中的 ServerEndpoint 的value值保持一致
path: "ws://localhost:8080/websocket/execute",
socket: "",
loading: false,
queryParams:{
}
}
},
mounted() {
this.init();
},
methods: {
init: function () {
if (typeof (WebSocket) === "undefined") {
console.log("浏览器不支持websocket");
} else {
//涉及到spring security鉴权,此处加上token (正常的http请求可以设置请求头,websocket无法设置,只好把token放在Sec-WebSocket-Protocol中)
let token = getToken();
this.socket = new WebSocket(this.path, [token]);
this.socket.onopen = this.open
this.socket.onerror = this.error
this.socket.onmessage = this.getMessage
}
},
open: function () {
console.log("websocket连接成功")
},
error: function (error) {
console.log("websocket连接错误", error)
},
getMessage: function (msg) {
console.log("收到消息,", msg);
},
send: function (params) {
this.socket.send(params)
},
close: function (e) {
console.log("websocket连接关闭")
},
submit: function (){
this.loading = true;
let params = JSON.stringify(this.queryParams);
this.send(params);
console.log("发送消息,", params);
this.loading = false;
}
},
destroyed() {
this.socket.onclose = this.close
}
}
</script>
后端代码
1、Config
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
2、在原来取token的地方加上判断(TokenService.getToken)
String token = request.getHeader(header);
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
token = token.replace(Constants.TOKEN_PREFIX, "");
}else {
//如果未从请求头中获取到token,则尝试从sec_websocket_protocol中取出
token = request.getHeader(Constants.WEBSOCKET_PROTOCOL);
//如果有值,一定要在response的header中设置,否则还是会断开
if (StringUtils.isNotEmpty(token)){
response.setHeader(Constants.WEBSOCKET_PROTOCOL, token);
}
}
3、controller中代码
@RestController
@ServerEndpoint(value = "/websocket/execute")
public class WebSocketController {
private final Logger logger = LoggerFactory.getLogger(getClass());
@OnMessage
public void onMessage(String msg, Session session){
logger.info("收到websocket消息, msg={}, session={}", msg, session);
if (StringUtils.isEmpty(msg)){
sendMsg("怎么是条空消息", session);
return;
}
SocketMsgVo msgVo = JSONObject.parseObject(msg, SocketMsgVo.class);
//TODO 分发消息
}
private void sendMsg(String msg, Session session){
try {
session.getBasicRemote().sendText(msg);
} catch (IOException e) {
logger.error("发送websocket消息错误, msg={}, session={}", msg, session);
logger.error("发送websocket消息错误", e);
}
}
@OnOpen
public void onOpen(Session session){
logger.info("连接打开咯, session={}", session);
}
@OnClose
public void onClose(Session session){
logger.info("连接关闭咯, session={}", session);
}
@OnError
public void onError(Session session, Throwable error){
logger.error("websocket发生错误, session={}", session);
logger.error("websocket发生错误, error={}", error);
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)