初始化成功

This commit is contained in:
rjb
2025-12-31 10:00:35 +08:00
parent 6166a7f559
commit 59efd72230
8 changed files with 420 additions and 5 deletions

121
OPPO_PUSH_README.md Normal file
View File

@@ -0,0 +1,121 @@
# OPPO推送服务配置说明
## 配置信息
已配置的OPPO推送参数
- **包名**: com.xunpaisoft.social
- **AppId**: 32150237
- **AppKey**: bb0819c889ae40cd8bde5a8ad4e670fe
- **AppSecret**: 9b5a0e6d560e406dbb70fbb4e0e38098
- **AppServerSecret**: 2d8b4e922d60453d987f0d09de6eb4a6
配置文件位置: `config/oppo.properties`
## 启动服务
### 1. 编译项目
```bash
cd /home/renjianbo/push/push_server
mvn clean package
```
### 2. 运行服务
编译成功后,在 `target` 目录找到 `push-xxxx.jar`,然后执行:
```bash
# 确保 config 目录在 jar 包同级目录
java -jar target/push-*.jar
```
或者后台运行:
```bash
nohup java -jar target/push-*.jar > push.log 2>&1 &
```
服务启动后,默认监听端口:**8085**
## 测试推送
### 方法1: 使用测试脚本
```bash
cd /home/renjianbo/push/push_server
./test_oppo_push.sh <device_token>
```
其中 `device_token` 是 OPPO 手机的 registration_id需要从 OPPO 手机应用中获取。
### 方法2: 使用 curl 命令
```bash
curl -X POST http://localhost:8085/android/push \
-H "Content-Type: application/json;charset=UTF-8" \
-d '{
"pushType": 5,
"pushMessageType": 0,
"packageName": "com.xunpaisoft.social",
"deviceToken": "YOUR_DEVICE_TOKEN",
"pushContent": "这是一条测试推送消息",
"sender": "test_user",
"senderName": "测试用户",
"target": "test_target",
"targetName": "测试目标",
"convType": 0,
"line": 0,
"cntType": 1,
"serverTime": 1234567890000,
"unReceivedMsg": 1,
"mentionedType": 0,
"isHiddenDetail": false,
"language": "zh",
"messageId": 1234567890,
"republish": false,
"existBadgeNumber": 0
}'
```
**注意**: 将 `YOUR_DEVICE_TOKEN` 替换为实际的 OPPO 设备 registration_id。
## 获取 Device Token
OPPO 手机的 registration_iddevice_token需要从以下方式获取
1. **从 OPPO 手机应用中获取**: 应用启动后OPPO Push SDK 会返回 registration_id
2. **查看应用日志**: 在应用日志中查找 registration_id
3. **从 OPPO 推送平台获取**: 登录 OPPO 开放平台,在推送统计中可以看到设备的 registration_id
## 验证推送
1. 确保 OPPO 手机已安装应用(包名: com.xunpaisoft.social
2. 确保应用已获取推送权限
3. 确保手机网络正常
4. 发送测试推送后,检查手机是否收到通知
5. 查看服务器日志: `tail -f push.log` 或查看控制台输出
## 常见问题
1. **推送失败**:
- 检查 device_token 是否正确
- 检查包名是否匹配com.xunpaisoft.social
- 检查服务器日志中的错误信息
2. **服务启动失败**:
- 检查端口 8085 是否被占用
- 检查 config 目录是否存在且配置文件正确
3. **配置不生效**:
- 确保 config 目录在 jar 包同级目录
- 检查配置文件格式是否正确
## 日志查看
服务日志文件: `push.log`
查看实时日志:
```bash
tail -f push.log
```

View File

@@ -1 +1 @@
server.port=8085
server.port=8080

View File

@@ -1,2 +1,6 @@
oppo.AppKey=16c6afe503b24259928e082ef01a6bf2
oppo.AppSecret=2114e4067de4424fbfc0638e311ce88c
# OPPO推送服务配置
# 包名: com.xunpaisoft.social
# AppId: 32150237
oppo.AppKey=bb0819c889ae40cd8bde5a8ad4e670fe
oppo.AppSecret=9b5a0e6d560e406dbb70fbb4e0e38098
oppo.AppServerSecret=2d8b4e922d60453d987f0d09de6eb4a6

123
push.log Normal file
View File

@@ -0,0 +1,123 @@
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/renjianbo/push/push_server-master/target/push-0.1.2.jar!/BOOT-INF/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/renjianbo/push/push_server-master/target/push-0.1.2.jar!/BOOT-INF/lib/log4j-slf4j-impl-2.17.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/renjianbo/push/push_server-master/target/push-0.1.2.jar!/BOOT-INF/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.6.RELEASE)
2025-12-31 09:59:06.314 INFO 24833 --- [ main] cn.wildfirechat.push.PushApplication : Starting PushApplication v0.1.2 on VM-4-13-centos with PID 24833 (/home/renjianbo/push/push_server-master/target/push-0.1.2.jar started by renjianbo in /home/renjianbo/push/push_server)
2025-12-31 09:59:06.321 INFO 24833 --- [ main] cn.wildfirechat.push.PushApplication : No active profile set, falling back to default profiles: default
2025-12-31 09:59:06.433 INFO 24833 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2a3046da: startup date [Wed Dec 31 09:59:06 CST 2025]; root of context hierarchy
2025-12-31 09:59:09.464 INFO 24833 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2025-12-31 09:59:09.508 INFO 24833 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2025-12-31 09:59:09.508 INFO 24833 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34
2025-12-31 09:59:09.574 INFO 24833 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2025-12-31 09:59:09.729 INFO 24833 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2025-12-31 09:59:09.729 INFO 24833 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3300 ms
2025-12-31 09:59:09.836 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2025-12-31 09:59:09.841 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2025-12-31 09:59:09.841 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2025-12-31 09:59:09.841 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2025-12-31 09:59:09.841 INFO 24833 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2025-12-31 09:59:10.031 INFO 24833 --- [ main] c.w.push.android.oppo.OppoPush : OppoPush init start, appKey: bb0819c889ae40cd8bde5a8ad4e670fe, appSecret: 9b5a0e6d56..., appServerSecret: 2d8b4e922d...
2025-12-31 09:59:10.917 INFO 24833 --- [ main] c.w.push.android.oppo.OppoPush : OppoPush init success, using secret: appServerSecret
2025-12-31 09:59:11.313 ERROR 24833 --- [ main] cn.wildfirechat.push.ios.ApnsServer : ApnsServer init failed
java.security.InvalidKeyException: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : null
at com.turo.pushy.apns.auth.ApnsSigningKey.loadFromInputStream(ApnsSigningKey.java:165)
at com.turo.pushy.apns.auth.ApnsSigningKey.loadFromPkcs8File(ApnsSigningKey.java:107)
at cn.wildfirechat.push.ios.ApnsServer.init(ApnsServer.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:309)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:416)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1686)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:581)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:370)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1336)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1135)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:581)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:370)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1336)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:548)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230)
at cn.wildfirechat.push.PushApplication.main(PushApplication.java:9)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : null
at sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:169)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
at com.turo.pushy.apns.auth.ApnsSigningKey.loadFromInputStream(ApnsSigningKey.java:163)
... 61 more
Caused by: java.security.InvalidKeyException: IOException : null
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351)
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356)
at sun.security.ec.ECPrivateKeyImpl.<init>(ECPrivateKeyImpl.java:81)
at sun.security.ec.ECKeyFactory.implGeneratePrivate(ECKeyFactory.java:237)
at sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:165)
... 63 more
2025-12-31 09:59:11.489 INFO 24833 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2025-12-31 09:59:11.858 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2a3046da: startup date [Wed Dec 31 09:59:06 CST 2025]; root of context hierarchy
2025-12-31 09:59:12.017 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/android/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.androidPush(cn.wildfirechat.push.PushMessage)
2025-12-31 09:59:12.019 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/ios/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.iOSPush(cn.wildfirechat.push.PushMessage)
2025-12-31 09:59:12.019 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/harmony/push],methods=[POST],produces=[application/json;charset=UTF-8]}" onto public java.lang.Object cn.wildfirechat.push.PushController.hmPush(cn.wildfirechat.push.PushMessage)
2025-12-31 09:59:12.024 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2025-12-31 09:59:12.024 INFO 24833 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2025-12-31 09:59:12.103 INFO 24833 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2025-12-31 09:59:12.104 INFO 24833 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2025-12-31 09:59:12.605 INFO 24833 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2025-12-31 09:59:12.669 INFO 24833 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2025-12-31 09:59:12.677 INFO 24833 --- [ main] cn.wildfirechat.push.PushApplication : Started PushApplication in 7.306 seconds (JVM running for 8.144)
2025-12-31 09:59:22.368 INFO 24833 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2025-12-31 09:59:22.389 INFO 24833 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 21 ms
2025-12-31 09:59:22.520 INFO 24833 --- [nio-8080-exec-1] c.w.push.android.AndroidPushServiceImpl : Android push {"sender":"test_user","senderName":"测试用户","convType":0,"target":"test_target","targetName":"测试目标","line":0,"cntType":1,"serverTime":1767146362000,"pushMessageType":0,"pushType":5,"pushContent":"这是一条测试推送消息 - 2025-12-31 09:59:22","unReceivedMsg":1,"mentionedType":0,"packageName":"com.xunpaisoft.social","deviceToken":"OPPO_CN_95ac9afc103d70bb26441ec0cbb06b97","isHiddenDetail":false,"language":"zh","messageId":1767146362,"callStartUid":0,"republish":false,"existBadgeNumber":0}
2025-12-31 09:59:22.626 INFO 24833 --- [pool-2-thread-1] c.w.push.android.oppo.OppoPush : Server response: MessageId: 32150237-1-1-6954837a1acc0c0174ca3d27 ErrorCode: ReturnCode{code=0, message='Success'} Reason: OK

View File

@@ -10,6 +10,7 @@ import org.springframework.context.annotation.PropertySource;
public class OppoConfig {
private String appSecret;
private String appKey;
private String appServerSecret;
public String getAppSecret() {
return appSecret;
@@ -26,4 +27,12 @@ public class OppoConfig {
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getAppServerSecret() {
return appServerSecret;
}
public void setAppServerSecret(String appServerSecret) {
this.appServerSecret = appServerSecret;
}
}

View File

@@ -28,9 +28,14 @@ public class OppoPush {
@PostConstruct
private void init() {
try {
mSender = new Sender(mConfig.getAppKey(), mConfig.getAppSecret());
// 根据 OPPO SDK 文档Sender 的第二个参数应该是 masterSecretappServerSecret
// 如果配置了 appServerSecret优先使用它否则使用 appSecret
String secret = mConfig.getAppServerSecret() != null ? mConfig.getAppServerSecret() : mConfig.getAppSecret();
mSender = new Sender(mConfig.getAppKey(), secret);
LOG.info("OppoPush initialized successfully with appKey: {}, using appServerSecret: {}",
mConfig.getAppKey(), mConfig.getAppServerSecret() != null);
} catch (Exception e) {
LOG.error("OppoPush init failed");
LOG.error("OppoPush init failed", e);
e.printStackTrace();
}
}

58
test_oppo_push.sh Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/bash
# OPPO推送测试脚本
# 使用方法: ./test_oppo_push.sh <device_token>
# device_token: OPPO手机的registration_id需要从OPPO手机应用中获取
if [ -z "$1" ]; then
echo "使用方法: $0 <device_token>"
echo "device_token: OPPO手机的registration_id"
echo ""
echo "示例: $0 1234567890abcdef"
exit 1
fi
DEVICE_TOKEN=$1
SERVER_URL="http://localhost:8080/android/push"
echo "正在测试OPPO推送..."
echo "设备Token: $DEVICE_TOKEN"
echo "服务器地址: $SERVER_URL"
echo ""
# 构建推送消息JSON
# pushType=5 表示 OPPO 推送类型
# packageName 需要与配置的包名一致: com.xunpaisoft.social
curl -X POST "$SERVER_URL" \
-H "Content-Type: application/json;charset=UTF-8" \
-d "{
\"pushType\": 5,
\"pushMessageType\": 0,
\"packageName\": \"com.xunpaisoft.social\",
\"deviceToken\": \"$DEVICE_TOKEN\",
\"pushContent\": \"这是一条测试推送消息\",
\"sender\": \"test_user\",
\"senderName\": \"测试用户\",
\"target\": \"test_target\",
\"targetName\": \"测试目标\",
\"convType\": 0,
\"line\": 0,
\"cntType\": 1,
\"serverTime\": $(date +%s)000,
\"unReceivedMsg\": 1,
\"mentionedType\": 0,
\"isHiddenDetail\": false,
\"language\": \"zh\",
\"messageId\": $(date +%s),
\"republish\": false,
\"existBadgeNumber\": 0
}"
echo ""
echo ""
echo "测试完成请检查OPPO手机是否收到推送消息。"
echo "如果推送失败,请检查:"
echo "1. 服务器是否已启动 (端口 8080)"
echo "2. device_token 是否正确需要从OPPO手机应用中获取"
echo "3. 查看服务器日志: tail -f push.log"

95
test_push_8080.sh Executable file
View File

@@ -0,0 +1,95 @@
#!/bin/bash
# OPPO推送测试脚本 (使用8080端口)
# 使用方法: ./test_push_8080.sh <device_token>
# device_token: OPPO手机的registration_id需要从OPPO手机应用中获取
if [ -z "$1" ]; then
echo "=========================================="
echo "OPPO推送测试脚本 (端口: 8080)"
echo "=========================================="
echo ""
echo "使用方法: $0 <device_token>"
echo ""
echo "device_token: OPPO手机的registration_id"
echo " (需要从OPPO手机应用中获取)"
echo ""
echo "示例: $0 1234567890abcdef1234567890abcdef"
echo ""
echo "如果没有device_token"
echo "1. 在OPPO手机上安装应用 (包名: com.xunpaisoft.social)"
echo "2. 启动应用并查看日志获取registration_id"
echo "3. 或者从OPPO推送平台查看设备列表"
exit 1
fi
DEVICE_TOKEN=$1
SERVER_URL="http://localhost:8080/android/push"
echo "=========================================="
echo "正在测试OPPO推送..."
echo "=========================================="
echo "设备Token: $DEVICE_TOKEN"
echo "服务器地址: $SERVER_URL"
echo "包名: com.xunpaisoft.social"
echo ""
# 构建推送消息JSON
# pushType=5 表示 OPPO 推送类型
TIMESTAMP=$(date +%s)
MESSAGE_ID=$TIMESTAMP
RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST "$SERVER_URL" \
-H "Content-Type: application/json;charset=UTF-8" \
-d "{
\"pushType\": 5,
\"pushMessageType\": 0,
\"packageName\": \"com.xunpaisoft.social\",
\"deviceToken\": \"$DEVICE_TOKEN\",
\"pushContent\": \"这是一条测试推送消息 - $(date '+%Y-%m-%d %H:%M:%S')\",
\"sender\": \"test_user\",
\"senderName\": \"测试用户\",
\"target\": \"test_target\",
\"targetName\": \"测试目标\",
\"convType\": 0,
\"line\": 0,
\"cntType\": 1,
\"serverTime\": ${TIMESTAMP}000,
\"unReceivedMsg\": 1,
\"mentionedType\": 0,
\"isHiddenDetail\": false,
\"language\": \"zh\",
\"messageId\": $MESSAGE_ID,
\"republish\": false,
\"existBadgeNumber\": 0
}")
HTTP_CODE=$(echo "$RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
BODY=$(echo "$RESPONSE" | sed '/HTTP_CODE:/d')
echo "----------------------------------------"
echo "服务器响应:"
echo "----------------------------------------"
echo "$BODY" | python -m json.tool 2>/dev/null || echo "$BODY"
echo ""
echo "HTTP状态码: $HTTP_CODE"
echo ""
if [ "$HTTP_CODE" = "200" ]; then
echo "✓ 推送请求已发送成功!"
echo ""
echo "请检查:"
echo "1. OPPO手机是否收到推送通知"
echo "2. 查看服务器日志了解详细推送结果"
else
echo "✗ 推送请求失败 (HTTP $HTTP_CODE)"
echo ""
echo "请检查:"
echo "1. 服务器是否正常运行在8080端口"
echo "2. device_token 是否正确"
echo "3. 查看服务器日志: tail -f push.log 或查看控制台输出"
fi
echo ""
echo "=========================================="