此文来讲讲怎么运用Sse大局单向音讯提示发送和物流信息对接。
一、Sse(Server-Send Events)
它是H5的api,用于在服务器和客户端之间实时推送数据流。Sse可以用于完成实时告诉、实时聊天、实时数据更新和实时监控等功能,而且可自动链接,和Websocket不同的是,它是单向的,只允许服务端向客户端实时推送,客户端向服务端发送不了数据音讯。
接下来讲不同文件里完成Sse。
1、首先咱们现在在Nest的项目里创立公共文件,写入项目注册Sse的node事情,来创立和调用Sse,代码如下:
import { EventEmitter } from 'node:events';
export class sseEvent {
private static sseEvent = new EventEmitter();
static getEvent () {
return this.sseEvent
}
}
2、在事务办法里注册并界说node事情,代码如下:
import { sseEvent } from 'src/common/sseEvent/utils';
sseEvent.getEvent().emit('send', data);
真实事务代码图:先去调用查事务相关表的办法,当然,有些事务场景是可以拿redis的,具体情况根据事务来。
3、在控制层创立Sse接口并触发方才现已注册好的node 事情,代码如下:
import { Observable, interval, map } from 'rxjs';
import { sseEvent } from 'src/common/sseEvent/utils';
export interface MessageEvent {
data: object;
}
/** Sse 查询音讯提示数量,可自界说为大局 */
@Sse('clientWeb/getMessageNum')
async sse(): Promise<Observable<MessageEvent>> {
return new Observable<any>((observer) => {
/** 此处触发方才注册好的node事情获取数据 */
sseEvent.getEvent().on('send', (data: any) => {
observer.next({ data: data });
});
});
}
真实事务代码图:
那为啥不直接写个查事务相关表的办法在上面调用呢?因为音讯提示是某一个事务场景触发的,打个比方,此时A职工填写好请假条,在create请假条的办法里界说node事情,及时触发Sse发送到审批人手里,总不能去轮询查对应的事务表来触发Sse发送吧。
4、前端代码如下:这儿用的Vue3和Ts
const isNoReadNumber = ref<Number>(); // 未读或者未审批的音讯
const eventSource = new EventSource(`${api}/api/public/clientWeb/getMessageNum`);
eventSource.onmessage = ({ data }) => {
isNoReadNumber.value = JSON.parse(data)?.isNoReadNumber
}
当然咱们可以获取登录用户的人物来获取对应的音讯提示,用户的信息存在redis,放在大局模块护卫,前端在headers里传过来的token去解析存在redis里对应的人物,来获取某人物的音讯。前提是创立音讯的时候,它得赋予某个人物/某个岗位/某个部分,可用相关表去相关对应的请假条id、人物id/岗位id/部分id。
二、物流信息对接
这儿对接的第三方渠道是快递鸟,可去百度查询,这儿就不贴地址以防说我是打广告的哈。
1、先创立好办法,创立办法前先装置依靠,注意:md5-hex不同的依靠版本对应不同的node版本,自己node版本的是16.18.0,所以装置的是3.0.1版本
装置依靠
npm install md5-hex@3.0.1
npm install querystring
装置好后写一个大局的办法可供其它办法调用,代码如下:
import { Injectable } from '@nestjs/common'
import querystring from 'querystring'
import { HttpService } from '@nestjs/axios'
import { lastValueFrom } from 'rxjs'
import md5Hex from 'md5-hex'
import { GetSettingService } from 'src/system/setting/get.setting.service'
@Injectable()
export class LogisticsService {
constructor(
private readonly getSettingService: GetSettingService,
private readonly http: HttpService,
) {}
// 获取系统设置,(先获取系统设置的快递装备信息)
async getSettingInfo() {
let settingInfo = await this.getSettingService.findOneInfo()
return settingInfo
}
// 查询物流
async sendLogistics() {
const { logisticsUserId, logisticsKey } = await this.getSettingInfo();
if (!logisticsUserId) return false; // 没填写用户id
if (!logisticsKey) return false; // 没填写api的key
const Url = 'https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx';
//请求接口指令
const RequestType = '1002';
// 组装应用级参数
const RequestData = {
'CustomerName': '',
'OrderCode': '',
'ShipperCode': 'STO', // 举个比如,申通快递
'LogisticCode': '7732684xxxxx', // 物流单号,可动态传进来,这儿举例就写死了
};
const DataSign = Buffer.from(md5Hex(JSON.stringify(RequestData)+logisticsKey)).toString('base64')
const reqParams = {
RequestType,
EBusinessID: logisticsUserId,
DataSign,
RequestData: JSON.stringify(RequestData),
DataType: 2
}
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
const { data } = await lastValueFrom(this.http.post(Url, querystring.stringify(reqParams), { headers }))
return data;
}
}
2、那咱们写个接口来测验测验,代码如下:
Service层
import { LogisticsService } from 'src/common/logistics/logistics.service'
// 后端接口回来封装,可自界说
import { ResultData } from '../../common/utils/result'
@Injectable()
export class SettingService {
constructor(
@InjectEntityManager()
private readonly logisticsService: LogisticsService,
) {}
/** 测验查询物流 */
async sendLogistics() {
const info = await this.logisticsService.sendLogistics();
if (!info) return ResultData.fail(AppHttpCode.USER_NOT_FOUND, '查询物流信息失败,请查看对应的装备信息是否填写')
return ResultData.ok(info);
}
}
Controller层
@ApiTags('系统设置模块')
@Controller('setting')
export class SettingController {
constructor(private readonly settingService: SettingService) {}
@Get('/sendLogistics')
@ApiOperation({ summary: '测验查询物流' })
@ApiResult()
async sendLogistics() {
return await this.settingService.sendLogistics();
}
}
来看看前端测验的结果,回来正常结果,就说明成功了。
这就是运用Sse 大局单向音讯提示发送和物流信息对接
以上代码都现已开源了,链接是:gitee.com/wx375149069… 此Nest开源项目包含以下丰富的功能,费事大家点个Start