当前位置: 首页 > news >正文

HTML5+ push消息推送

HTML5+ push消息推送

  • push消息推送
  • 关键 API 介绍
    • plus.push
      • addEventListener
      • clear
      • createMessage
      • getAllMessage
      • getClientInfo
      • setAutoNotification
      • remove
  • 实践
    • 消息推送
    • 开启权限

push消息推送

HTML5+ 的 Push 消息推送功能是一个强大的特性,它允许开发者在 Web 应用中实现服务端向客户端主动推送消息的能力。这种机制对于提升用户体验、实现实时通信等场景非常有用。
HTML5+ 是对 HTML5 标准的扩展,它提供了一系列增强的 API 以支持更丰富的 Web 应用功能。Push 消息推送是其中之一,它允许开发者通过特定的 API 接收来自服务端的消息,并在客户端进行展示或处理。

关键 API 介绍

plus.push

plus.push 是 HTML5+ 中用于管理推送消息的主要对象。通过它,开发者可以添加事件监听器、清空推送消息、创建本地消息、获取所有推送消息、获取客户端推送标识信息等。

addEventListener

addEventListener:添加推送消息事件监听器,支持的事件类型包括“click”(用户点击推送消息)、“receive”(应用接收到推送消息)等。

void plus.push.addEventListener( type, listener, Boolean );
  • type: ( String ) 必选 事件类型
    支持事件类型:“click”-从系统消息中心点击消息启动应用事件;“receive”-应用从推送服务器接收到推送消息事件。
  • listener: ( PushReceiveCallback ) 必选 事件监听器回调函数,在接收到推送消息时调用
  • capture: ( Boolean ) 可选 是否捕获事件,此处可忽略

clear

clear:清空所有推送消息,包括系统消息中心中的推送消息。

void plus.push.clear();

createMessage

createMessage:在本地创建推送消息,并添加到系统消息中心。

void plus.push.createMessage( content, payload, option );

参数

  • content: ( String ) 必选
    消息显示的内容,在系统通知中心中显示的文本内容。
  • payload: ( String | Object ) 可选
    消息承载的数据,可根据业务逻辑自定义数据格式。
  • options: ( MessageOptions ) 可选
    创建消息的额外参数,参考MessageOptions。

返回值
void : 无

getAllMessage

getAllMessage:获取客户端接收到的所有推送消息。 仅包括在系统消息中心显示的推送消息,不包括调用setAutoNotification(false)方法设置不显示推送消息后接收到的消息。

PushMessage[] plus.push.getAllMessage();

返回值:
PushMessage : Array[PushMessage]对象,推送消息PushMessage数组。

getClientInfo

getClientInfo:获取客户端的推送标识信息,如设备令牌(token)、推送服务令牌(clientid)等。
客户端标识信息用于业务服务器下发推送消息时提交给推送服务器的数据,用于说明下发推送消息的接收者(客户端)。 通常需要客户端在第一次运行时获取并提交到业务服务器绑定。

ClientInfo plus.push.getClientInfo();

返回值:
ClientInfo : 客户端推送标识信息对象

setAutoNotification

setAutoNotification:设置程序是否将接收到的推送消息显示在系统消息中心。

默认情况下程序在接收到推送消息后将会在系统消息中心显示,通过此方法可关闭默认行为,
接收到推送消息后不在系统消息中心显示,通过addEventListener方法的“receive”事件监听处理接收到的消息。在这种模式下可通过createMessage方法创建在系统消息中心显示的消息。
void plus.push.setAutoNotification( notify );

参数:
notify: ( Boolean ) 必选 是否自动提示推送消息
可取值true或false,true表示自动显示推送消息,false则不显示。默认值为true。
返回值:
void : 无

remove

remove:删除指定的推送消息,但 iOS 平台不支持对单条消息的删除操作。
删除系统消息中心指定的推送消息,可通过getAllMessage方法获取所有的消息后进行操作。

void plus.push.remove( message )

参数:
message: ( PushMessage ) 必选 要删除的消息对象,可通过getAllMessage()方法来获取消息。
返回值:
void : 无

实践

消息推送代码在onLaunch生命周期中监听

onLaunch: function() {isAppLunched = false// asyncClientInfo()getUserInfoAsync({connectSocket: true}).then(() => {setTimeout(() => {initPlusListener()  //消息推送initPlusPermissions()  //通知权限isAppLunched = true}, 1000)})},

消息推送

export const initPlusListener = () => {plus.push.setAutoNotification(true)  //设置了推送消息的自动通知功能// ios端 存在点击异常: https://ask.dcloud.net.cn/question/135753plus.push.addEventListener('receive', (msg) => {try {//handleAppNoticeReceive(msg)//处理接收到的消息} catch (error) {track( 'appMsgNoticeReceive', { msg, desc: '处理出错' })}}, false)plus.push.addEventListener('click', (msg) => {try {//当用户点击通知栏中的推送消息时,会触发这个事件。//在事件处理函数中,调用 handleAppNoticeClick 函数来处理点击事件。handleAppNoticeClick(msg)} catch (error) {track('appMsgNoticeClick', { msg, desc: '处理出错' })}}, false)
}
//收到透传消息    
//只有APP在线时,才会触发receive事件,透传消息不会触发系统消息,需要创建本地消息  
const handleAppNoticeReceive = (rawMsg) => {let msgPayload = {}log.info('[handleAppNoticeReceive] 收到推送消息 ', JSON.stringify(rawMsg))track( 'appMsgNoticeReceive', { rawMsg, desc: '收到推送消息' })//尝试解析消息rawMsg.payload赋给msgPayloadtry {if (typeof rawMsg.payload === 'string') { //如果是字符串msgPayload = JSON.parse(rawMsg.payload)} else if(isPlainObject(rawMsg.payload)) {  //如果是object对象msgPayload = rawMsg.payload}} catch(e) {const desc =  '解析 app 消息 msg.payload 异常'track( 'appMsgNoticeReceive', { rawMsg, desc })log.error(desc, e)	return}//从 msgPayload 中提取 data 字段,并解构出 id, shortMessage, title, type。const msgData = get(msgPayload,'data') || msgPayload || {}const { id, shortMessage, title, type } = msgData//验证 id 和 type 是否存在,以及 shortMessage 和 title 是否为空。如果验证失败,记录错误并返回。if (isUndefined(id) || isUndefined(type)) {const desc = '消息携带 data 数据中 id,type 异常'log.error(desc, msgData)	track( 'appMsgNoticeReceive', { msgData, desc })return}if (!shortMessage || !title) {const desc = '消息携带 data 数据中 shortMessage,title 异常'log.error(desc, msgData)	track( 'appMsgNoticeReceive', { msgData, desc })return}//记录解析成功的消息数据track( 'appMsgNoticeReceive', {msgData,desc: '解析 msgPayload.data 数据'})log.info('解析 msgPayload.data 数据', msgData)	// TODO: 不本地创建消息,可能存在BUG 推送太多。// plus.push.createMessage(shortMessage, rawMsg.payload, {title});  // setAppBadgeNum('message', 1); 
}
//消息点击事件    
//【APP在线】,收到透传消息通过,不会提醒至通知栏目,需要发送本地消息,再进行点击触发的点击事件。    
//【APP离线】,收到离线透传消息,必须通过Java后台的Intent字符串携带payload,且符合格式才能触发click事件,格式不符合不会触发
const handleAppNoticeClick = (rawMsg) => {//日志记录和跟踪log.info('[handleAppNoticeClick] 点击推送消息 ', JSON.stringify(rawMsg))track( 'appMsgNoticeClick', { rawMsg, desc: '点击推送消息' })//尝试解析 rawMsg.payload,如果解析失败则记录错误并返回。let msgPayload = {}try {if (typeof rawMsg.payload === 'string') {msgPayload = JSON.parse(rawMsg.payload)} else if(isPlainObject(rawMsg.payload)) {msgPayload = rawMsg.payload}} catch(e) {const desc =  '解析 app 消息 msg.payload 异常'track( 'appMsgNoticeClick', { rawMsg, desc })// 解析 app 消息 msg.payload 异常log.error(desc, e)return	}//从 msgPayload 中提取 data 字段,并解构出 ext, id, type, orgId, orgName。const msgData = get(msgPayload,'data') || msgPayload || {}const { ext, id, type, orgId = '', orgName = ''} = msgData//验证 id 和 type 是否存在。如果验证失败,记录错误并返回。if (isUndefined(id) || isUndefined(type)) {const desc = '消息携带 data 数据中 id,type 异常'log.error(desc, msgData)	track( 'appMsgNoticeClick', { msgData, desc })return}//记录解析成功的消息数据track( 'appMsgNoticeClick', {msgData,desc: '解析 msgPayload.data 数据'})log.info('解析 msgPayload.data 数据', msgData)	//解析 ext 字段,如果解析失败则记录错误并返回。(ext是从传递进来的参数里解析出来的数据)let extInfo = {}if (typeof ext === 'string' && ext !== '' && ext !== 'null') {try {extInfo = JSON.parse(ext) // TODO: 提取逻辑} catch(e) {// 解析 消息数据中 ext 信息异常const desc = '解析 消息数据中 ext 信息异常'log.error(desc, e)	track('appMsgNoticeClick', {ext, desc })return}}//根据 type(根据传递进来的参数解析出来的) 的值进行不同的页面导航,并记录相应的跟踪信息。let routeData = {}switch (type == 0) {case 0: routeData = {id,orgId,orgName}track( 'appMsgNoticeClick', { desc: '进入 bjjk', routeData })navToPage('console.alarm.detail', routeData)breakcase 1: routeData = {id,orgId,orgName,title: extInfo.modelName,...extInfo,}track( 'appMsgNoticeClick', { desc: '进入 mxjk', routeData })navToPage('console.model.detail', routeData)breakcase 2: if (extInfo.isBatch) {track( 'appMsgNoticeClick', { desc: 'gd列表' })navToPage('console.work.orgList')return}routeData = {orgId,info: {status: extInfo.status || 0,id: extInfo.ticketId,type: extInfo.ticketType}}track( 'appMsgNoticeClick', { desc: '进入 gd详情', routeData })navToPage('console.work.workDetail', routeData)break}
}

开启权限

export const initPlusPermissions = () => {try {plus.screen.lockOrientation('portrait-primary') //竖屏正方向锁定handleNoticePermission()} catch (error) {log.error('initPlusPermissions error', error)//}
}
const handleNoticePermission = () => {let type = uni.getSystemInfoSync().platformif (type === 'android') {var main = plus.android.runtimeMainActivity();var pkName = main.getPackageName();var NotificationManagerCompat = plus.android.importClass("android.support.v4.app.NotificationManagerCompat");if (NotificationManagerCompat == null) {NotificationManagerCompat = plus.android.importClass('androidx.core.app.NotificationManagerCompat');}var packageNames = NotificationManagerCompat.from(main);if (!packageNames.areNotificationsEnabled()) { //手机没有开启通知的权限uni.showModal({title: '通知管理',content: '是否允许消息推送',success: function(res) {if (res.confirm) {var uid = main.getApplicationInfo().plusGetAttribute("uid");var Intent = plus.android.importClass('android.content.Intent');var Build = plus.android.importClass("android.os.Build");//android 8.0引导  if (Build.VERSION.SDK_INT >= 26) {var intent = new Intent('android.settings.APP_NOTIFICATION_SETTINGS');intent.putExtra('android.provider.extra.APP_PACKAGE', pkName);} else if (Build.VERSION.SDK_INT >= 21) { //android 5.0-7.0  var intent = new Intent('android.settings.APP_NOTIFICATION_SETTINGS');intent.putExtra("app_package", pkName);intent.putExtra("app_uid", uid);} else { //(<21)其他--跳转到该应用管理的详情页var Settings = plus.android.importClass("android.provider.Settings");var Uri = plus.android.importClass("android.net.Uri");var intent = new Intent();intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);var uri = Uri.fromParts("package", main.getPackageName(), null);intent.setData(uri);}// 跳转到该应用的系统通知设置页  main.startActivity(intent);} else if (res.cancel) {}}});}return}if (type === 'ios') {var UIApplication = plus.ios.import("UIApplication");var app = UIApplication.sharedApplication();var enabledTypes = 0;if (app.currentUserNotificationSettings) {var settings = app.currentUserNotificationSettings();enabledTypes = settings.plusGetAttribute("types");// console.log("enabledTypes1:" + enabledTypes);if (enabledTypes == 0) {plus.nativeUI.confirm("消息推送没有开启,是否去开启?", function(e) {if (e.index == 0) {var NSURL2 = plus.ios.import("NSURL");var setting2 = NSURL2.URLWithString("app-settings:");var application2 = UIApplication.sharedApplication();application2.openURL(setting2);plus.ios.deleteObject(setting2);plus.ios.deleteObject(NSURL2);plus.ios.deleteObject(application2);}}, {"buttons": ["Yes", "No"],"verticalAlign": "center"});}plus.ios.deleteObject(settings);} else {enabledTypes = app.enabledRemoteNotificationTypes();if (enabledTypes == 0) {console.log("推送未开启!");} else {console.log("已经开启推送功能!")}console.log("enabledTypes2:" + enabledTypes);}plus.ios.deleteObject(app);}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【面经】C++八股文(地平线C++一面)
  • WebGL-编译报错,如何定位sendfile报错位置
  • java事务回滚原理 Java事务回滚的实现及流程
  • AFAC2024-基于保险条款的问答 比赛日记 llamafactory qwen npu 910B1
  • 微软CrowdStrike驱动蓝屏以及内核签名
  • 谷粒商城实战笔记-45-商品服务-API-三级分类-查询-递归树形结构数据获取
  • Lua 语法学习笔记
  • 【safari】react在safari浏览器中,遇到异步时间差的问题,导致状态没有及时更新到state,引起传参错误。如何解决
  • 压缩包方式windows安装mysql
  • ORBSLAM3 ORB_SLAM3 Ubuntu20.04 ROS Noetic 虚拟机镜像 下载
  • 【漏洞复现】Netgear WN604 downloadFile.php 信息泄露漏洞(CVE-2024-6646)
  • CCF-CSP认证考试 202406-2 矩阵重塑(其二) 100分题解
  • 如何查看jvm资源占用情况
  • JavaScript(11)——对象
  • SSD基本架构与工作原理
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【刷算法】从上往下打印二叉树
  • 2019.2.20 c++ 知识梳理
  • Brief introduction of how to 'Call, Apply and Bind'
  • Docker: 容器互访的三种方式
  • ECS应用管理最佳实践
  • SpingCloudBus整合RabbitMQ
  • SQLServer插入数据
  • TypeScript实现数据结构(一)栈,队列,链表
  • webpack4 一点通
  • 飞驰在Mesos的涡轮引擎上
  • 简单实现一个textarea自适应高度
  • 将回调地狱按在地上摩擦的Promise
  • 前端之Sass/Scss实战笔记
  • 山寨一个 Promise
  • 实现菜单下拉伸展折叠效果demo
  • 写代码的正确姿势
  • HanLP分词命名实体提取详解
  • ​TypeScript都不会用,也敢说会前端?
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #define
  • #QT(智能家居界面-界面切换)
  • (12)目标检测_SSD基于pytorch搭建代码
  • (16)Reactor的测试——响应式Spring的道法术器
  • (C11) 泛型表达式
  • (Java数据结构)ArrayList
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (十六)串口UART
  • (万字长文)Spring的核心知识尽揽其中
  • (一) storm的集群安装与配置
  • . NET自动找可写目录
  • .gitignore不生效的解决方案
  • .NET CLR Hosting 简介
  • .NET Core 中插件式开发实现
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET 事件模型教程(二)
  • .NET 依赖注入和配置系统
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证