Commit c1145a816399528e81589eef11046d877315ad5e

Authored by 648540858
1 parent 15169913

优化级联注册,以及sip日志

src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java
1 1 package com.genersoft.iot.vmp.gb28181.conf;
2 2  
  3 +import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd.AlarmNotifyMessageHandler;
  4 +import org.slf4j.Logger;
  5 +import org.slf4j.LoggerFactory;
  6 +
3 7 import java.util.Properties;
4 8  
5 9 /**
... ... @@ -12,6 +16,7 @@ public class DefaultProperties {
12 16 Properties properties = new Properties();
13 17 properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
14 18 properties.setProperty("javax.sip.IP_ADDRESS", ip);
  19 + // 关闭自动会话
15 20 properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off");
16 21 /**
17 22 * 完整配置参考 gov.nist.javax.sip.SipStackImpl,需要下载源码
... ... @@ -26,7 +31,7 @@ public class DefaultProperties {
26 31 // 接收所有notify请求,即使没有订阅
27 32 properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
28 33 properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
29   - properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "false");
  34 + properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "true");
30 35 // 为_NULL _对话框传递_终止的_事件
31 36 properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");
32 37 // 会话清理策略
... ... @@ -35,11 +40,33 @@ public class DefaultProperties {
35 40 properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
36 41 // 获取实际内容长度,不使用header中的长度信息
37 42 properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
  43 + // 线程可重入
  44 + properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true");
  45 + // 定义应用程序打算多久审计一次 SIP 堆栈,了解其内部线程的健康状况(该属性指定连续审计之间的时间(以毫秒为单位))
  46 + properties.setProperty("gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS", "30000");
38 47  
39 48 /**
40 49 * sip_server_log.log 和 sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
41 50 */
42   - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
  51 + Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class);
  52 + if (logger.isDebugEnabled()) {
  53 + System.out.println("DEBUG");
  54 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "DEBUG");
  55 + }else if (logger.isInfoEnabled()) {
  56 + System.out.println("INFO1");
  57 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
  58 + }else if (logger.isWarnEnabled()) {
  59 + System.out.println("WARNING");
  60 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "WARNING");
  61 + }else if (logger.isErrorEnabled()) {
  62 + System.out.println("ERROR");
  63 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "ERROR");
  64 + }else {
  65 + System.out.println("INFO2");
  66 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "INFO");
  67 + }
  68 + logger.info("[SIP日志]级别为: {}", properties.getProperty("gov.nist.javax.sip.TRACE_LEVEL"));
  69 +
43 70  
44 71 return properties;
45 72 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/conf/SipLoggerPass.java deleted 100644 → 0
1   -package com.genersoft.iot.vmp.gb28181.conf;
2   -
3   -import gov.nist.core.StackLogger;
4   -
5   -import java.util.Properties;
6   -
7   -/**
8   - * sip日志格式化
9   - * 暂不使用
10   - */
11   -public class SipLoggerPass implements StackLogger {
12   -
13   - @Override
14   - public void logStackTrace() {
15   -
16   - }
17   -
18   - @Override
19   - public void logStackTrace(int traceLevel) {
20   -
21   - }
22   -
23   - @Override
24   - public int getLineCount() {
25   - return 0;
26   - }
27   -
28   - @Override
29   - public void logException(Throwable ex) {
30   -
31   - }
32   -
33   - @Override
34   - public void logDebug(String message) {
35   -
36   - }
37   -
38   - @Override
39   - public void logDebug(String message, Exception ex) {
40   -
41   - }
42   -
43   - @Override
44   - public void logTrace(String message) {
45   -
46   - }
47   -
48   - @Override
49   - public void logFatalError(String message) {
50   -
51   - }
52   -
53   - @Override
54   - public void logError(String message) {
55   -
56   - }
57   -
58   - @Override
59   - public boolean isLoggingEnabled() {
60   - return false;
61   - }
62   -
63   - @Override
64   - public boolean isLoggingEnabled(int logLevel) {
65   - return false;
66   - }
67   -
68   - @Override
69   - public void logError(String message, Exception ex) {
70   -
71   - }
72   -
73   - @Override
74   - public void logWarning(String string) {
75   -
76   - }
77   -
78   - @Override
79   - public void logInfo(String string) {
80   -
81   - }
82   -
83   - @Override
84   - public void disableLogging() {
85   -
86   - }
87   -
88   - @Override
89   - public void enableLogging() {
90   -
91   - }
92   -
93   - @Override
94   - public void setBuildTimeStamp(String buildTimeStamp) {
95   -
96   - }
97   -
98   - @Override
99   - public void setStackProperties(Properties stackProperties) {
100   -
101   - }
102   -
103   - @Override
104   - public String getLoggerName() {
105   - return null;
106   - }
107   -}
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
... ... @@ -13,7 +13,6 @@ import javax.sip.SipFactory;
13 13 import javax.sip.header.FromHeader;
14 14 import javax.sip.header.Header;
15 15 import javax.sip.header.UserAgentHeader;
16   -import javax.sip.header.ViaHeader;
17 16 import javax.sip.message.Request;
18 17 import java.text.ParseException;
19 18 import java.util.ArrayList;
... ... @@ -138,13 +137,12 @@ public class SipUtils {
138 137 }else {
139 138 // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息
140 139 // 获取到通信地址等信息
141   - ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
142   - remoteAddress = viaHeader.getReceived();
143   - remotePort = viaHeader.getRPort();
  140 + remoteAddress = request.getTopmostViaHeader().getReceived();
  141 + remotePort = request.getTopmostViaHeader().getRPort();
144 142 // 解析本地地址替代
145 143 if (ObjectUtils.isEmpty(remoteAddress) || remotePort == -1) {
146   - remoteAddress = viaHeader.getHost();
147   - remotePort = viaHeader.getPort();
  144 + remoteAddress = request.getTopmostViaHeader().getHost();
  145 + remotePort = request.getTopmostViaHeader().getPort();
148 146 }
149 147 }
150 148  
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -424,7 +424,7 @@ public class ZLMHttpHookListener {
424 424 logger.info("[ZLM HOOK]流无人观看:{]->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
425 425 JSONObject ret = new JSONObject();
426 426 ret.put("code", 0);
427   - // 录像下载
  427 + // 国标类型的流
428 428 if ("rtp".equals(param.getApp())){
429 429 ret.put("close", userSetting.getStreamOnDemand());
430 430 // 国标流, 点播/录像回放/录像下载
... ... @@ -596,7 +596,7 @@ public class ZLMHttpHookListener {
596 596 @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8")
597 597 public JSONObject onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param){
598 598  
599   - logger.info("[ZLM HOOK] 发送rtp被动关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
  599 + logger.info("[ZLM HOOK] rtp发送关闭:{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
600 600  
601 601 JSONObject ret = new JSONObject();
602 602 ret.put("code", 0);
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
... ... @@ -154,7 +154,8 @@ public class DeviceServiceImpl implements IDeviceService {
154 154 }
155 155 // 刷新过期任务
156 156 String registerExpireTaskKey = registerExpireTaskKeyPrefix + device.getDeviceId();
157   - dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), device.getExpires() * 1000);
  157 + // 增加一个10秒给设备重发消息的机会
  158 + dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId()), (device.getExpires() + 10) * 1000);
158 159 }
159 160  
160 161 @Override
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
... ... @@ -135,14 +135,7 @@ public class PlatformServiceImpl implements IPlatformService {
135 135 dynamicTask.startCron(registerTaskKey,
136 136 // 注册失败(注册成功时由程序直接调用了online方法)
137 137 ()-> {
138   - try {
139   - logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId());
140   - commanderForPlatform.register(parentPlatform, eventResult -> {
141   - offline(parentPlatform, false);
142   - },null);
143   - } catch (InvalidArgumentException | ParseException | SipException e) {
144   - logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage());
145   - }
  138 + registerTask(parentPlatform);
146 139 },
147 140 (parentPlatform.getExpires() - 10) *1000);
148 141 }
... ... @@ -194,6 +187,28 @@ public class PlatformServiceImpl implements IPlatformService {
194 187 }
195 188 }
196 189  
  190 + private void registerTask(ParentPlatform parentPlatform){
  191 + try {
  192 + // 设置超时重发, 后续从底层支持消息重发
  193 + String key = KEEPALIVE_KEY_PREFIX + parentPlatform.getServerGBId() + "_timeout";
  194 + if (dynamicTask.isAlive(key)) {
  195 + return;
  196 + }
  197 + dynamicTask.startDelay(key, ()->{
  198 + registerTask(parentPlatform);
  199 + }, 1000);
  200 + logger.info("[国标级联] 平台:{}注册即将到期,重新注册", parentPlatform.getServerGBId());
  201 + commanderForPlatform.register(parentPlatform, eventResult -> {
  202 + dynamicTask.stop(key);
  203 + offline(parentPlatform, false);
  204 + },eventResult -> {
  205 + dynamicTask.stop(key);
  206 + });
  207 + } catch (InvalidArgumentException | ParseException | SipException e) {
  208 + logger.error("[命令发送失败] 国标级联定时注册: {}", e.getMessage());
  209 + }
  210 + }
  211 +
197 212 @Override
198 213 public void offline(ParentPlatform parentPlatform, boolean stopRegister) {
199 214 logger.info("[平台离线]:{}", parentPlatform.getServerGBId());
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
... ... @@ -106,24 +106,21 @@ public class PlayController {
106 106 msg.setData(wvpResult);
107 107 resultHolder.invokeResult(msg);
108 108 });
109   -
110   -
111   - // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误
112   - deferredResultEx.setFilter(result1 -> {
113   - WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1;
114   - WVPResult<StreamContent> resultStream = null;
115   - if (wvpResult1.getCode() == ErrorCode.SUCCESS.getCode()) {
116   - StreamInfo data = wvpResult1.getData().clone();
117   - if (userSetting.getUseSourceIpAsStreamIp()) {
118   - data.channgeStreamIp(request.getLocalName());
119   - }
120   - resultStream = new WVPResult<>();
121   - resultStream.setCode(wvpResult1.getCode());
122   - resultStream.setMsg(wvpResult1.getMsg());
123   - resultStream.setData(new StreamContent(wvpResult1.getData()));
  109 + // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误
  110 + deferredResultEx.setFilter(result1 -> {
  111 + WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1;
  112 + WVPResult<StreamContent> resultStream = new WVPResult<>();
  113 + resultStream.setCode(wvpResult1.getCode());
  114 + resultStream.setMsg(wvpResult1.getMsg());
  115 + if (wvpResult1.getCode() == ErrorCode.SUCCESS.getCode()) {
  116 + StreamInfo data = wvpResult1.getData().clone();
  117 + if (userSetting.getUseSourceIpAsStreamIp()) {
  118 + data.channgeStreamIp(request.getLocalName());
124 119 }
125   - return resultStream;
126   - });
  120 + resultStream.setData(new StreamContent(wvpResult1.getData()));
  121 + }
  122 + return resultStream;
  123 + });
127 124  
128 125  
129 126 // 录像查询以channelId作为deviceId查询
... ...
src/main/resources/all-application.yml
... ... @@ -186,7 +186,7 @@ user-settings:
186 186 use-pushing-as-status: true
187 187 # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启
188 188 use-source-ip-as-stream-ip: true
189   - # 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放
  189 + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放
190 190 stream-on-demand: true
191 191 # 推流鉴权, 默认开启
192 192 push-authority: true
... ... @@ -195,8 +195,8 @@ user-settings:
195 195 gb-send-stream-strict: false
196 196 # 设备上线时是否自动同步通道
197 197 sync-channel-on-device-online: false
198   - # 设备上线时是否自动同步通道
199   - sip-use-source-ip-as-remote-address: true
  198 + # 是否使用设备来源Ip作为回复IP, 不设置则为 false
  199 + sip-use-source-ip-as-remote-address: false
200 200  
201 201 # 关闭在线文档(生产环境建议关闭)
202 202 springdoc:
... ...