SimpleAdmin手摸手教学之:即时通讯

一、前言

作为前后端分离项目,前后端交互是一个非常重要的功能。目前主流框架都是通过Socket实现,本系统自然也是实现了基于Signalr的前后端交互,并在此基础上实现了基于MQTT的前后端交互功能,MQTT相比socket业务场景更多更灵活,在物联网方向有着非常多的应用。在工业物联网方向,mqtt也是应用非常广泛,最为.neter来说学习mqtt很有必要。

二、基于Signalr

系统默认是用的Signalr做前后端通信,关于Signalr使用文档可以去看Furion的文档:https://furion.baiqian.ltd/docs/signalr

2.1 后端部分

首先需要在启动时注册signalr服务和集线器。

新建一个集线器,在类名上加上MapHub特性,这样我们前端就能通过signalr连接到后端。

2.2 前端部分

前端的signalr基于"@microsoft/signalr": "^7.0.0" 可以在package.json中查看,关于signalr的连接也是非常简单,我封装在了utils文件夹下的signalr.js

import { Modal } from'ant-design-vue'import sysConfig from'@/config/index'import tool from'@/utils/tool'import * as signalR from'@microsoft/signalr'import * as signalrMessage from'./mqtt/message'//使用signalrexportdefaultfunctionuseSignalr() {
    const userInfo = tool.data.get('USER_INFO') //用户信息let socketUrl = '/hubs/simple'//socket地址if (sysConfig.VITE_PROXY === 'false') {
        socketUrl = sysConfig.API_URL + socketUrl //判断是否要走代理模式,走了的话发布之后直接nginx代理
    }
    //开始const startSignalr = () => {
        //初始化连接const connection = init()
        // 启动连接
        connection.start().then(() => {
            console.log('启动连接')
        })
    }

    //初始化const init = () => {
        console.log('初始化SignalR对象')
        // SignalR对象const connection = new signalR.HubConnectionBuilder()
            .withUrl(socketUrl, {
                accessTokenFactory: () => tool.data.get(sysConfig.ACCESS_TOEKN_KEY)
            })
            .withAutomaticReconnect({
                nextRetryDelayInMilliseconds: () => {
                    return5000// 每5秒重连一次
                }
            }) //自动重新连接
            .configureLogging(signalR.LogLevel.Information)
            .build()
        connection.keepAliveIntervalInMilliseconds = 15 * 1000// 心跳检测15s// connection.serverTimeoutInMilliseconds = 30 * 60 * 1000 // 超时时间30m// 断开连接
        connection.onclose(async () => {
            console.log('断开连接')
        })

        //断线重新
        connection.onreconnected(() => {
            console.log('断线重新连接成功')
        })
        //消息处理
        receiveMsg(connection)
        return connection
    }

    //接收消息处理const receiveMsg = (connection) => {
        // 接收登出
        connection.on('LoginOut', (data) => {
            signalrMessage.loginOut(data)
        })
    }

    //页面销毁
    onUnmounted(() => {})
    return { startSignalr }
}

使用也是很简单,只需要在需要连接的页面引用usesignalr,在本系统中,我们需要全局监听,所以我在layout文件夹下的index.vue中启用signalr并封装一个方法用来连接signalr

import useSignalr from'@/utils/signalr'//连接signalr
connectSignalr() {
    const { startSignalr } = useSignalr()
    startSignalr()
}

然后在页面created的最后连接signalr就行

F12查看控制台输出,登录系统之后,应该会提示连接singlar成功。

三、基于Mqtt

如果使用mqtt则需要一个mqtt broker来进行数据中转,前端和后端都是通过客户端的方式去连接服务端,然后再通过发布/订阅的方式进行数据交互。这里mqtt broker推荐使用emqx来搭建。

下载地址:https://www.emqx.com/zh/try?product=broker

后端mqtt客户端基于我自己封装的SimpleMQTT组件,gitee地址:https://gitee.com/zxzyjs/SimpleMQTT.git

前端基于"mqtt": "^4.3.7",可在package.json中查看。

3.1 MQTT配置

既然登录系统需要用户名/密码登录,那么连接mqtt服务器也应该需要账号密码才行,然而如果将账号密码信息写在前端配置文件中是不安全的,别有用心的人可能会盗取我们的用户名和密码。而且账号密码写死在前端也显得不那么灵活,如果账号密码修改了需要重新打包上传发布。基于以上两种情况,本系统将mqtt配置改为可配置化,用户可以在系统运维->系统配置->MQTT配置中配置域名和账号密码。

3.2 后端部分

首先需要在SimpleAdmin.Web.Core项目的配置文件中的WebSettings打开mqtt配置。

配置账号密码

系统会自动注册mqtt服务,连接mqttbroker

因为我们mqtt的连接信息都是存储在后端,前端想要连接就得通过接口获取连接信息,所以我们需要写一个接口来返回连接信息和订阅的主题。

3.3 前端部分

首先需要在配置文件中设置 VITE_MQTT = true

关于mqtt的封装可以在utils下的mqtt文件夹中找到。

mqtt.js

 

usemqtt.js

 

在需要启用mqtt的页面引入usemqtt并封装成方法

import useMqtt from'@/utils/mqtt/usemqtt'//连接mqtt
connectMqtt() {
    const { startMqtt } = useMqtt()
    startMqtt()
},

这样在系统启动时就会启用mqtt而不是singalr

F12查看控制台输出,登录系统之后已经成功连上mqtt服务器并订阅了Topic

四、在线用户

通过即时通讯我们可以判断当前用户是否在线,原理非常简单,用户登录系统后,无论哪种方式后台都会收到当前token连接了,然后把当前连接的客户端ID存储到该token信息中的客户端id列表中,当用户关闭了浏览器或者网络断开了连接,则会将断开的客户端idtoken中的客户端id列表中删除。在前端会话管理中只需要判断当前token的客户端id列表是否有数据就行了,如果有就是在线,如果没有就是离线。

4.1 Signalr方式

集线器里重写OnDisconnectedAsyncOnConnectedAsync方法

收到连接或断开的请求后更新redis

4.2 mqtt方式

对应signalrOnConnectedAsyncOnDisconnectedAsyncmqtt叫做上线下线,设备上线代表连接到服务器,设备下线代表断开服务器,通过emqx我们可以订阅上下线主题获取设备的上下线信息。所以我们需要启动一个客户端后台去订阅上下线事件,并且不能像iis那样会被回收,所以我们可以通过建立workerservice项目来后台运行。对应的SimpleAdmin.Background后台服务层。

MqttWorker中监听设备上下线主题,然后根据客户端id去更新redis就行了,原理和signalr一样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值