From d6675e84fecab6cf40bf08419d45eae1a233b221 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Mon, 25 Apr 2022 13:56:30 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A0signalR?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env.development | 5 ++-
.env.production | 3 ++
.env.staging | 5 ++-
package.json | 1 +
src/App.vue | 19 ++++++++
src/main.js | 5 ++-
src/store/getters.js | 3 +-
src/store/index.js | 4 +-
src/store/modules/socket.js | 30 +++++++++++++
src/utils/signalR.js | 87 +++++++++++++++++++++++++++++++++++++
10 files changed, 157 insertions(+), 5 deletions(-)
create mode 100644 src/store/modules/socket.js
create mode 100644 src/utils/signalR.js
diff --git a/.env.development b/.env.development
index fcfd516..086d1fa 100644
--- a/.env.development
+++ b/.env.development
@@ -9,4 +9,7 @@ VITE_APP_BASE_API = '/dev-api'
VITE_APP_ROUTER_PREFIX = '/'
# 默认上传地址
-VITE_APP_UPLOAD_URL = '/Common/UploadFile'
\ No newline at end of file
+VITE_APP_UPLOAD_URL = '/Common/UploadFile'
+
+#socket API
+VITE_APP_SOCKET_API = 'http://localhost:8888/msghub'
\ No newline at end of file
diff --git a/.env.production b/.env.production
index 044da0c..069cc48 100644
--- a/.env.production
+++ b/.env.production
@@ -10,3 +10,6 @@ VITE_APP_ROUTER_PREFIX = '/'
# 默认上传地址
VITE_APP_UPLOAD_URL = '/Common/UploadFile'
+
+#socket API
+VITE_APP_SOCKET_API = '/msghub'
\ No newline at end of file
diff --git a/.env.staging b/.env.staging
index 47b99fd..62f968e 100644
--- a/.env.staging
+++ b/.env.staging
@@ -12,4 +12,7 @@ VITE_APP_ROUTER_PREFIX = '/'
VITE_APP_UPLOAD_URL = '/Common/UploadFile'
# 是否在打包时开启压缩,支持 gzip 和 brotli
-VITE_BUILD_COMPRESS = gzip
\ No newline at end of file
+VITE_BUILD_COMPRESS = gzip
+
+#socket API
+VITE_APP_SOCKET_API = '/msghub'
\ No newline at end of file
diff --git a/package.json b/package.json
index 02e1173..af02d37 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
},
"dependencies": {
"@element-plus/icons-vue": "0.2.4",
+ "@microsoft/signalr": "^6.0.4",
"axios": "0.24.0",
"clipboard": "^2.0.10",
"echarts": "5.2.2",
diff --git a/src/App.vue b/src/App.vue
index 98240ae..2fec866 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,3 +1,22 @@
+
diff --git a/src/main.js b/src/main.js
index d39632d..d3acb01 100644
--- a/src/main.js
+++ b/src/main.js
@@ -14,6 +14,7 @@ import directive from './directive' // directive
// 注册指令
import plugins from './plugins' // plugins
// import { download } from '@/utils/request'
+import signalR from '@/utils/signalR'
// svg图标
import 'virtual:svg-icons-register'
@@ -42,7 +43,9 @@ import TreeSelect from '@/components/TreeSelect'
import DictTag from '@/components/DictTag'
const app = createApp(App)
-
+signalR.init(
+ import.meta.env.VITE_APP_SOCKET_API)
+app.config.globalProperties.signalr = signalR
// 全局方法挂载
app.config.globalProperties.getConfigKey = getConfigKey
app.config.globalProperties.getDicts = getDicts
diff --git a/src/store/getters.js b/src/store/getters.js
index 87d7e85..52841cf 100644
--- a/src/store/getters.js
+++ b/src/store/getters.js
@@ -16,6 +16,7 @@ const getters = {
topbarRouters: state => state.permission.topbarRouters,
defaultRoutes: state => state.permission.defaultRoutes,
sidebarRouters: state => state.permission.sidebarRouters,
- onlineUserNum: state => 0
+ onlineUserNum: state => state.socket.onlineNum,
+ noticeList: state => state.socket.noticeList
}
export default getters
\ No newline at end of file
diff --git a/src/store/index.js b/src/store/index.js
index d441545..4836b28 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -5,6 +5,7 @@ import tagsView from './modules/tagsView'
import permission from './modules/permission'
import settings from './modules/settings'
import getters from './getters'
+import socket from './modules/socket'
const store = createStore({
modules: {
@@ -12,7 +13,8 @@ const store = createStore({
user,
tagsView,
permission,
- settings
+ settings,
+ socket
},
getters
});
diff --git a/src/store/modules/socket.js b/src/store/modules/socket.js
new file mode 100644
index 0000000..5d9935b
--- /dev/null
+++ b/src/store/modules/socket.js
@@ -0,0 +1,30 @@
+const state = {
+ onlineNum: 0,
+ noticeList: []
+}
+const mutations = {
+ SET_ONLINEUSER_NUM: (state, num) => {
+ state.onlineNum = num
+ },
+ SET_NOTICE_list: (state, data) => {
+ state.noticeList = data;
+ }
+}
+
+const actions = {
+ //更新在线人数
+ changeOnlineNum({ commit }, data) {
+ commit('SET_ONLINEUSER_NUM', data)
+ },
+ // 更新系统通知
+ getNoticeList({ commit }, data) {
+ commit('SET_NOTICE_list', data)
+ }
+}
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions
+}
\ No newline at end of file
diff --git a/src/utils/signalR.js b/src/utils/signalR.js
new file mode 100644
index 0000000..f105071
--- /dev/null
+++ b/src/utils/signalR.js
@@ -0,0 +1,87 @@
+// 官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-2.2&tabs=visual-studio
+import * as signalR from '@microsoft/signalr'
+import store from '../store'
+import { getToken } from '@/utils/auth'
+import { ElNotification } from 'element-plus'
+
+export default {
+ // signalR对象
+ SR: {},
+ // 失败连接重试次数
+ failNum: 4,
+ baseUrl: '',
+ init(url) {
+ console.log(url);
+ const connection = new signalR.HubConnectionBuilder()
+ .withUrl(url, { accessTokenFactory: () => getToken() })
+ .withAutomaticReconnect()//自动重新连接
+ .configureLogging(signalR.LogLevel.Information)
+ .build();
+ this.SR = connection;
+ // 断线重连
+ connection.onclose(async () => {
+ console.log('断开连接了')
+ console.assert(connection.state === signalR.HubConnectionState.Disconnected);
+ // 建议用户重新刷新浏览器
+ await this.start();
+ })
+
+ connection.onreconnected(() => {
+ console.log('断线重新连接成功')
+ })
+ this.receiveMsg(connection);
+ // 启动
+ // this.start();
+ },
+ /**
+ * 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")})
+ * @returns
+ */
+ async start() {
+ var that = this;
+
+ try {
+ //使用async和await 或 promise的then 和catch 处理来自服务端的异常
+ await this.SR.start();
+ //console.assert(this.SR.state === signalR.HubConnectionState.Connected);
+ console.log('signalR 连接成功了', this.SR.state);
+ return true;
+ } catch (error) {
+ that.failNum--;
+ console.log(`失败重试剩余次数${that.failNum}`, error)
+ if (that.failNum > 0) {
+ setTimeout(async () => {
+ await this.SR.start()
+ }, 5000);
+ }
+ return false;
+ }
+ },
+ // 接收消息处理
+ receiveMsg(connection) {
+ connection.on("onlineNum", (data) => {
+ store.dispatch("socket/changeOnlineNum", data);
+ });
+ // 接收欢迎语
+ connection.on("welcome", (data) => {
+ console.log('welcome', data)
+ ElNotification.info(data)
+ });
+ // 接收后台手动推送消息
+ connection.on("receiveNotice", (title, data) => {
+ ElNotification({
+ type: 'info',
+ title: title,
+ message: data,
+ dangerouslyUseHTMLString: true,
+ duration: 0
+ })
+ })
+ // 接收系统通知/公告
+ connection.on("moreNotice", (data) => {
+ if (data.code == 200) {
+ store.dispatch("socket/getNoticeList", data.data);
+ }
+ })
+ }
+}
\ No newline at end of file