diff --git a/Postman使用说明.txt b/Postman使用说明.txt new file mode 100644 index 0000000..e9d852b --- /dev/null +++ b/Postman使用说明.txt @@ -0,0 +1,244 @@ +================================================================================ + Postman 测试 Honor 推送详细操作指南 +================================================================================ + +方法一:导入配置文件(推荐) +================================================================================ + +步骤1:打开 Postman + - 启动 Postman 应用程序 + +步骤2:导入配置文件 + - 点击左上角的 "Import" 按钮 + - 选择 "File" 标签 + - 浏览并选择文件:test_push_postman.json + - 点击 "Import" 完成导入 + +步骤3:使用导入的请求 + - 在左侧 Collections 中找到 "Honor Push Test" + - 点击 "Send Honor Push" 请求 + - 修改 deviceToken 为实际的设备Token + - 点击 "Send" 按钮发送请求 + +步骤4:查看响应 + - 在底部 Response 区域查看返回结果 + - 如果返回 "ok" 表示请求已接收 + + +方法二:手动创建请求(详细步骤) +================================================================================ + +步骤1:创建新请求 + - 点击左上角的 "+" 或 "New" 按钮 + - 选择 "HTTP Request" + - 或者直接点击 "New" 标签页 + +步骤2:设置请求方法 + - 在请求方法下拉菜单中选择 "POST" + - 默认是 "GET",需要改为 "POST" + +步骤3:输入请求URL + - 在 URL 输入框中输入: + http://localhost:8080/android/push + +步骤4:设置请求头(Headers) + - 点击 "Headers" 标签 + - 添加以下请求头: + Key: Content-Type + Value: application/json;charset=UTF-8 + - 注意:取消勾选 "Content-Type" 旁边的自动添加选项(如果有) + +步骤5:设置请求体(Body) + - 点击 "Body" 标签 + - 选择 "raw" 选项 + - 在右侧下拉菜单中选择 "JSON" + - 在文本框中输入以下JSON内容: + +{ + "sender": "test_sender_001", + "senderName": "测试用户", + "senderPortrait": "", + "convType": 0, + "target": "honor_device_001", + "targetName": "Honor设备", + "targetPortrait": "", + "userId": "honor_device_001", + "line": 0, + "cntType": 1, + "serverTime": 1767511609324, + "pushMessageType": 0, + "pushType": 8, + "pushContent": "这是一条使用Postman发送的测试推送消息", + "pushData": "", + "unReceivedMsg": 1, + "mentionedType": 0, + "packageName": "com.xunpaisoft.social.im", + "deviceToken": "BAEAAAAAB.josybFY8YYNOK7suCSammWuFIaIUgCdo1d5Ud2NBTUWnyy2a8yUG2WpwNiTZFgBW3sRPO_q-a1bWjwu_ODI6HWHHszoUi1HbhlhMaxjHmOs-zxfg--SECc", + "voipDeviceToken": "", + "isHiddenDetail": false, + "language": "zh_CN", + "messageId": 0, + "callStartUid": 0, + "republish": false, + "existBadgeNumber": 0 +} + +步骤6:修改参数(重要) + - 将 "deviceToken" 的值改为实际的设备Token + - 将 "serverTime" 改为当前时间戳(毫秒) + 可以使用在线工具获取,或使用JavaScript:Date.now() + - 可以修改 "pushContent" 为自定义的推送内容 + - 可以修改 "senderName" 为自定义的发送者名称 + +步骤7:发送请求 + - 点击右上角的蓝色 "Send" 按钮 + - 等待响应返回 + +步骤8:查看响应结果 + - 在底部 "Response" 区域查看结果 + - 如果状态码是 200,响应内容是 "ok",表示请求成功 + - 可以查看 "Headers"、"Body"、"Cookies" 等详细信息 + + +重要参数说明 +================================================================================ + +必须修改的参数: +1. deviceToken: 设备Token,必须使用实际的设备Token + 格式:BAEAAAAAB.xxxxx... + +2. serverTime: 服务器时间戳(毫秒) + 可以使用当前时间:Date.now() 或 new Date().getTime() + 示例:1767511609324 + +可选修改的参数: +1. pushContent: 推送消息内容 + 示例:"这是一条测试推送消息" + +2. senderName: 发送者名称 + 示例:"测试用户" + +3. target: 接收者ID + 示例:"honor_device_001" + +4. sender: 发送者ID + 示例:"test_sender_001" + + +使用环境变量(高级用法) +================================================================================ + +步骤1:创建环境 + - 点击右上角的 "No Environment" 下拉菜单 + - 选择 "Manage Environments" + - 点击 "Add" 创建新环境 + - 命名为 "Push Test" + +步骤2:添加变量 + 在环境中添加以下变量: + - base_url: http://localhost:8080 + - device_token: 你的设备Token + - app_package: com.xunpaisoft.social.im + +步骤3:在请求中使用变量 + - URL中使用:{{base_url}}/android/push + - Body中使用:{{device_token}}、{{app_package}} + +步骤4:切换环境 + - 在右上角选择创建的环境 + - 这样可以在不同环境间快速切换 + + +常见问题 +================================================================================ + +问题1:返回 404 Not Found +解决: + - 检查URL是否正确:http://localhost:8080/android/push + - 确认推送服务正在运行 + - 检查端口是否为8080 + +问题2:返回 400 Bad Request +解决: + - 检查JSON格式是否正确 + - 确认Content-Type设置为application/json + - 检查必填字段是否都有值 + +问题3:返回 "unknown push type" +解决: + - 确认 pushType 设置为 8(不是9) + - 检查JSON中的pushType字段 + +问题4:JSON格式错误 +解决: + - 使用Postman的格式化功能(点击"Pretty") + - 检查是否有未闭合的括号 + - 检查字符串是否用双引号 + +问题5:无法连接到服务器 +解决: + - 检查推送服务是否启动 + - 检查防火墙设置 + - 尝试使用 127.0.0.1 代替 localhost + + +快速测试步骤(简化版) +================================================================================ + +1. 打开Postman +2. 点击 "New" → "HTTP Request" +3. 方法选择 "POST" +4. URL输入:http://localhost:8080/android/push +5. 点击 "Body" → 选择 "raw" → 选择 "JSON" +6. 粘贴以下JSON(记得修改deviceToken): + +{ + "sender": "test_sender_001", + "senderName": "测试用户", + "convType": 0, + "target": "honor_device_001", + "targetName": "Honor设备", + "userId": "honor_device_001", + "line": 0, + "cntType": 1, + "serverTime": 1767511609324, + "pushMessageType": 0, + "pushType": 8, + "pushContent": "Postman测试消息", + "pushData": "", + "unReceivedMsg": 1, + "mentionedType": 0, + "packageName": "com.xunpaisoft.social.im", + "deviceToken": "你的设备Token", + "voipDeviceToken": "", + "isHiddenDetail": false, + "language": "zh_CN", + "messageId": 0, + "callStartUid": 0, + "republish": false, + "existBadgeNumber": 0 +} + +7. 点击 "Send" +8. 查看响应结果 + + +保存请求(便于重复使用) +================================================================================ + +步骤1:保存请求 + - 点击 "Save" 按钮 + - 输入请求名称,如:"Honor Push Test" + - 选择或创建Collection(集合) + - 点击 "Save" + +步骤2:重复使用 + - 在左侧 Collections 中找到保存的请求 + - 点击即可使用 + - 可以修改参数后再次发送 + + +================================================================================ +文档生成时间:2026-01-04 +================================================================================ + diff --git a/Untitled b/Untitled new file mode 100644 index 0000000..a31be7c --- /dev/null +++ b/Untitled @@ -0,0 +1 @@ +https://github.com/wildfirechat/push_server.git \ No newline at end of file diff --git a/push_server b/push_server new file mode 160000 index 0000000..6166a7f --- /dev/null +++ b/push_server @@ -0,0 +1 @@ +Subproject commit 6166a7f559609fc887032c3b1af5b00afb9fe9c6 diff --git a/test_honor_push.py b/test_honor_push.py new file mode 100644 index 0000000..e4a434f --- /dev/null +++ b/test_honor_push.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +测试 Honor 推送脚本 +""" +import json +import requests +import time + +# 推送服务地址 +PUSH_SERVER_URL = "http://localhost:8080/android/push" + +# 用户提供的 token +DEVICE_TOKEN = "BAEAAAAAB.josybFY8YYNOK7suCSammWuFIaIUgCdo1d5Ud2NBTUWnyy2a8yUG2WpwNiTZFgBW3sRPO_q-a1bWjwu_ODI6HWHHszoUi1HbhlhMaxjHmOs-zxfg--SECc" + +# Honor 推送类型(注意:实际运行的推送服务版本中使用的是 8,不是 9) +ANDROID_PUSH_TYPE_HONOR = 8 + +# 普通消息类型 +PUSH_MESSAGE_TYPE_NORMAL = 0 + +def send_honor_push(title="测试消息", content="这是一条测试推送消息", sender="test_user", target="honor_device"): + """ + 发送 Honor 推送消息 + + Args: + title: 推送标题 + content: 推送内容 + sender: 发送者ID + target: 接收者ID + """ + # 构建推送消息 + push_message = { + "sender": sender, + "senderName": "测试用户", + "senderPortrait": "", + "convType": 0, # 0: 单聊, 1: 群聊, 3: 聊天室 + "target": target, + "targetName": "Honor设备", + "targetPortrait": "", + "userId": target, + "line": 0, + "cntType": 1, # 消息内容类型 + "serverTime": int(time.time() * 1000), # 服务器时间(毫秒) + "pushMessageType": PUSH_MESSAGE_TYPE_NORMAL, # 0: 普通消息 + "pushType": ANDROID_PUSH_TYPE_HONOR, # 9: Honor推送 + "pushContent": content, # 推送内容 + "pushData": "", # 推送数据(可选) + "unReceivedMsg": 1, # 未接收消息数 + "mentionedType": 0, # 0: 无@提醒, 1: @了当前用户, 2: @了所有人 + "packageName": "com.xunpaisoft.social.im", # 应用包名(根据配置文件中的badgeClass推断) + "deviceToken": DEVICE_TOKEN, # 设备token + "voipDeviceToken": "", + "isHiddenDetail": False, # 是否隐藏详情 + "language": "zh_CN", # 语言 + "messageId": 0, + "callStartUid": 0, + "republish": False, + "existBadgeNumber": 0 + } + + print("=" * 60) + print("发送 Honor 推送消息") + print("=" * 60) + print(f"推送服务地址: {PUSH_SERVER_URL}") + print(f"设备Token: {DEVICE_TOKEN[:50]}...") + print(f"推送标题: {title}") + print(f"推送内容: {content}") + print("=" * 60) + + try: + # 发送 POST 请求 + response = requests.post( + PUSH_SERVER_URL, + json=push_message, + headers={"Content-Type": "application/json;charset=UTF-8"}, + timeout=10 + ) + + print(f"\n响应状态码: {response.status_code}") + print(f"响应内容: {response.text}") + + if response.status_code == 200: + print("\n✓ 推送请求发送成功!") + print("请检查手机是否收到推送通知。") + else: + print(f"\n✗ 推送请求失败,状态码: {response.status_code}") + + except requests.exceptions.ConnectionError: + print("\n✗ 无法连接到推送服务!") + print("请确保推送服务正在运行在 http://localhost:8080") + except requests.exceptions.Timeout: + print("\n✗ 请求超时!") + except Exception as e: + print(f"\n✗ 发生错误: {str(e)}") + +if __name__ == "__main__": + # 发送测试推送 + send_honor_push( + title="测试推送", + content="这是一条来自推送服务的测试消息,如果您收到此消息,说明推送配置成功!", + sender="test_sender_001", + target="honor_device_001" + ) + diff --git a/推送测试详细流程说明.txt b/推送测试详细流程说明.txt new file mode 100644 index 0000000..4f69933 --- /dev/null +++ b/推送测试详细流程说明.txt @@ -0,0 +1,353 @@ +================================================================================ + Honor 推送测试详细流程说明文档 +================================================================================ + +一、整体架构 +================================================================================ + +推送测试系统采用分层架构,从测试脚本到最终手机接收,经过以下层次: + +Python测试脚本 → 推送服务(Java Spring Boot) → Honor推送API → Honor服务器 → 手机设备 + +-------------------------------------------------------------------------------- +层次说明: +1. 测试脚本层:使用Python构建推送消息并发送HTTP请求 +2. 推送服务层:Java Spring Boot服务,接收请求并路由到对应厂商 +3. Honor推送层:处理Honor特定的推送逻辑 +4. Honor API层:调用Honor官方推送接口 +5. 设备层:手机接收推送通知 +-------------------------------------------------------------------------------- + + +二、详细流程步骤 +================================================================================ + +【步骤1】Python测试脚本构建推送消息 +-------------------------------------------------------------------------------- +文件:test_honor_push.py + +1.1 定义关键参数: + - 推送服务地址:http://localhost:8080/android/push + - 设备Token:BAEAAAAAB.josybFY8YYNOK7suCSammWuFIaIUgCdo1d5Ud2NBTUWnyy2a8yUG2WpwNiTZFgBW3sRPO_q-a1bWjwu_ODI6HWHHszoUi1HbhlhMaxjHmOs-zxfg--SECc + - 推送类型:8 (ANDROID_PUSH_TYPE_HONOR) + - 消息类型:0 (普通消息) + +1.2 构建推送消息JSON对象,包含以下字段: + { + "sender": "test_sender_001", // 发送者ID + "senderName": "测试用户", // 发送者名称 + "target": "honor_device_001", // 接收者ID + "pushType": 8, // Honor推送类型 + "pushContent": "推送内容", // 推送消息内容 + "deviceToken": "设备Token", // 设备唯一标识 + "packageName": "com.xunpaisoft.social.im", // 应用包名 + "serverTime": 时间戳(毫秒), // 服务器时间 + ... 其他字段 + } + +1.3 发送HTTP POST请求: + - URL: http://localhost:8080/android/push + - Content-Type: application/json;charset=UTF-8 + - Body: 上述JSON对象 + + +【步骤2】推送服务接收请求 +-------------------------------------------------------------------------------- +文件:PushController.java +路径:/android/push + +2.1 Spring Boot接收HTTP POST请求 +2.2 使用@RequestBody自动将JSON反序列化为PushMessage对象 +2.3 调用AndroidPushService.push()方法 + + +【步骤3】推送服务路由处理 +-------------------------------------------------------------------------------- +文件:AndroidPushServiceImpl.java + +3.1 日志记录:记录接收到的推送消息 +3.2 消息过滤检查: + - 检查是否被过滤(Utility.filterPush) + - 检查是否为朋友圈消息(line == 1) + - 如果被过滤,返回"Canceled" + +3.3 异步处理: + - 使用线程池(ExecutorService)异步执行推送 + - 立即返回"ok",不等待推送完成 + - 设置超时保护(15秒) + +3.4 根据pushType路由到对应厂商: + switch (pushMessage.getPushType()) { + case 8: // ANDROID_PUSH_TYPE_HONOR + honorPush.push(pushMessage); + break; + case 1: // 小米 + case 2: // 华为 + case 3: // 魅族 + ... 其他厂商 + } + + +【步骤4】Honor推送处理 +-------------------------------------------------------------------------------- +文件:HonorPush.java + +4.1 Token管理: + - 检查accessToken是否有效(未过期) + - 如果无效,调用refreshToken()刷新 + - Token有效期:3600秒(1小时) + - 提前5分钟刷新,避免过期 + +4.2 获取认证Token(refreshToken方法): + - URL: https://iam.developer.honor.com/auth/token + - 方法:POST + - 参数: + * grant_type=client_credentials + * client_secret={appSecret} + * client_id={appId} + - 响应:包含access_token和expires_in + +4.3 构建Honor API请求体: + - 调用RequestBody.buildRequestBody()方法 + - 将PushMessage转换为Honor API格式 + - 包含字段: + * notification.title: 推送标题 + * notification.body: 推送内容 + * token: [设备Token数组] + * android.notification: Android特定配置 + * android.notification.badge: 角标配置 + +4.4 调用Honor推送API: + - URL: https://push-api.cloud.honor.com/api/v1/{appId}/sendMessage + - 方法:POST + - Headers: + * Content-Type: application/json + * Authorization: Bearer {accessToken} + * timestamp: 当前时间戳 + - Body: Honor API格式的JSON + +4.5 处理响应: + - 记录响应日志 + - 检查响应中的code和message + - 如果成功:{"code":200,"message":"Success","data":{"sendResult":true}} + + +【步骤5】Honor服务器处理 +-------------------------------------------------------------------------------- +5.1 Honor服务器验证: + - 验证accessToken有效性 + - 验证appId和appSecret + - 验证设备Token有效性 + +5.2 推送消息到设备: + - 通过Honor推送通道发送到指定设备 + - 使用设备Token定位设备 + + +【步骤6】手机设备接收 +-------------------------------------------------------------------------------- +6.1 Honor系统接收推送 +6.2 根据packageName匹配应用 +6.3 显示推送通知 +6.4 用户点击后打开应用(使用badgeClass指定的Activity) + + +三、关键技术点 +================================================================================ + +1. 异步处理机制 + - 使用线程池异步执行推送,避免阻塞HTTP请求 + - 立即返回"ok",提高响应速度 + - 适合高并发场景 + +2. Token缓存机制 + - 缓存accessToken,避免频繁请求 + - 自动刷新,提前5分钟刷新避免过期 + - 减少API调用次数 + +3. 多厂商支持 + - 通过pushType路由到不同厂商实现 + - 统一的PushMessage接口 + - 各厂商独立实现 + +4. 配置管理 + - 配置文件:config/honor.properties + - 关键配置: + * honor.appSecret: 应用密钥 + * honor.appId: 应用ID + * honor.badgeClass: 应用入口Activity + +5. 错误处理 + - Token刷新失败:记录错误并返回 + - API调用失败:记录异常日志 + - 超时保护:15秒超时丢弃消息 + + +四、配置文件说明 +================================================================================ + +文件:config/honor.properties + +honor.appSecret=8cdcbb2485c3f333fa8fd226707212adbe95d733bb672933c14c0d72e60b550f +honor.appId=104475849 +honor.badgeClass=com.xunpaisoft.social.im.main.MainActivity + +说明: +- appSecret和appId:用于获取Honor推送服务的认证Token,必须正确 +- badgeClass:应用入口Activity,用于推送点击后打开应用 + + +五、数据流转图 +================================================================================ + +┌─────────────────┐ +│ Python测试脚本 │ +│ test_honor_push │ +│ .py │ +└────────┬────────┘ + │ HTTP POST (JSON) + │ http://localhost:8080/android/push + ▼ +┌─────────────────┐ +│ PushController │ +│ (Spring Boot) │ +└────────┬────────┘ + │ 调用 + ▼ +┌─────────────────┐ +│AndroidPushService│ +│ Impl (路由) │ +└────────┬────────┘ + │ pushType=8 + ▼ +┌─────────────────┐ +│ HonorPush │ +│ (处理层) │ +└────────┬────────┘ + │ 1. 检查/刷新Token + │ 2. 构建请求体 + │ 3. 调用API + ▼ +┌─────────────────┐ +│ Honor推送API │ +│ push-api.cloud. │ +│ honor.com │ +└────────┬────────┘ + │ 推送消息 + ▼ +┌─────────────────┐ +│ Honor服务器 │ +│ (消息分发) │ +└────────┬────────┘ + │ 通过推送通道 + ▼ +┌─────────────────┐ +│ 手机设备 │ +│ (接收通知) │ +└─────────────────┘ + + +六、重要注意事项 +================================================================================ + +1. 推送类型问题 + - 源码中定义:ANDROID_PUSH_TYPE_HONOR = 9 + - 实际运行版本使用:pushType = 8 + - 测试脚本需要使用8才能正常工作 + +2. 端口配置 + - 推送服务运行在:8080端口 + - 测试脚本连接:http://localhost:8080/android/push + +3. 返回"ok"不代表推送成功 + - "ok"只表示请求已接收 + - 实际推送在后台异步执行 + - 需要查看日志确认推送结果 + +4. 配置参数重要性 + - appSecret和appId错误:无法获取Token,推送完全失败 + - badgeClass错误:可能影响推送或点击行为 + - 必须从Honor开发者平台获取正确的配置 + +5. 设备Token + - 必须通过客户端SDK获取 + - Token可能过期,需要定期更新 + - 不同设备有不同的Token + + +七、日志查看 +================================================================================ + +推送服务日志位置:/home/renjianbo/push/push_server/push.log + +关键日志信息: +1. "Android push {...}" - 接收到的推送消息 +2. "Honor refresh token" - 刷新Token +3. "Honor token refreshed successfully" - Token刷新成功 +4. "Push message {...}" - 发送给Honor的请求体 +5. "Push to ... response {...}" - Honor API的响应 + +查看命令: +tail -f /home/renjianbo/push/push_server/push.log | grep -i honor + + +八、常见问题排查 +================================================================================ + +问题1:返回"ok"但手机收不到推送 +排查步骤: +1. 查看推送服务日志,确认是否调用了HonorPush +2. 检查Token是否成功获取 +3. 查看Honor API响应,确认sendResult是否为true +4. 检查设备Token是否有效 +5. 检查手机通知权限和网络连接 + +问题2:显示"unknown push type" +原因:pushType不正确 +解决:使用pushType=8(不是9) + +问题3:Token刷新失败 +原因:appSecret或appId配置错误 +解决:检查honor.properties配置文件 + +问题4:推送服务连接失败 +原因:推送服务未启动或端口不对 +解决:确认服务运行在8080端口 + + +九、测试脚本使用 +================================================================================ + +文件:test_honor_push.py + +使用方法: +python3 test_honor_push.py + +修改参数: +- DEVICE_TOKEN:修改为实际的设备Token +- title和content:修改推送标题和内容 +- sender和target:修改发送者和接收者ID + +注意事项: +- 确保推送服务正在运行 +- 确保设备Token有效 +- 确保配置文件正确 + + +十、总结 +================================================================================ + +推送测试系统通过分层架构实现了从测试脚本到手机设备的完整推送流程。 +关键特点是: +1. 异步处理,提高性能 +2. Token缓存,减少API调用 +3. 多厂商支持,统一接口 +4. 配置分离,易于管理 + +整个流程是异步的,测试脚本发送请求后立即返回,实际推送在后台执行。 +要确认推送是否成功,需要查看推送服务的日志文件。 + +================================================================================ +文档生成时间:2026-01-04 +================================================================================ +