初始化成功
This commit is contained in:
121
OPPO_PUSH_README.md
Normal file
121
OPPO_PUSH_README.md
Normal 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_id(device_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
|
||||||
|
```
|
||||||
|
|
||||||
@@ -1 +1 @@
|
|||||||
server.port=8085
|
server.port=8080
|
||||||
@@ -1,2 +1,6 @@
|
|||||||
oppo.AppKey=16c6afe503b24259928e082ef01a6bf2
|
# OPPO推送服务配置
|
||||||
oppo.AppSecret=2114e4067de4424fbfc0638e311ce88c
|
# 包名: com.xunpaisoft.social
|
||||||
|
# AppId: 32150237
|
||||||
|
oppo.AppKey=bb0819c889ae40cd8bde5a8ad4e670fe
|
||||||
|
oppo.AppSecret=9b5a0e6d560e406dbb70fbb4e0e38098
|
||||||
|
oppo.AppServerSecret=2d8b4e922d60453d987f0d09de6eb4a6
|
||||||
123
push.log
Normal file
123
push.log
Normal 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
|
||||||
@@ -10,6 +10,7 @@ import org.springframework.context.annotation.PropertySource;
|
|||||||
public class OppoConfig {
|
public class OppoConfig {
|
||||||
private String appSecret;
|
private String appSecret;
|
||||||
private String appKey;
|
private String appKey;
|
||||||
|
private String appServerSecret;
|
||||||
|
|
||||||
public String getAppSecret() {
|
public String getAppSecret() {
|
||||||
return appSecret;
|
return appSecret;
|
||||||
@@ -26,4 +27,12 @@ public class OppoConfig {
|
|||||||
public void setAppKey(String appKey) {
|
public void setAppKey(String appKey) {
|
||||||
this.appKey = appKey;
|
this.appKey = appKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAppServerSecret() {
|
||||||
|
return appServerSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppServerSecret(String appServerSecret) {
|
||||||
|
this.appServerSecret = appServerSecret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,9 +28,14 @@ public class OppoPush {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
private void init() {
|
private void init() {
|
||||||
try {
|
try {
|
||||||
mSender = new Sender(mConfig.getAppKey(), mConfig.getAppSecret());
|
// 根据 OPPO SDK 文档,Sender 的第二个参数应该是 masterSecret(appServerSecret)
|
||||||
|
// 如果配置了 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) {
|
} catch (Exception e) {
|
||||||
LOG.error("OppoPush init failed");
|
LOG.error("OppoPush init failed", e);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
58
test_oppo_push.sh
Executable file
58
test_oppo_push.sh
Executable 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
95
test_push_8080.sh
Executable 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 "=========================================="
|
||||||
|
|
||||||
Reference in New Issue
Block a user