Jelajahi Sumber

添加zlm重连机制

kindring 2 tahun lalu
induk
melakukan
272af1a1e4

+ 3 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java

@@ -788,9 +788,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
         Device device = redisCatchStorage.getDevice(requesterId);
         if (device != null) {
             logger.info("收到设备" + requesterId + "的语音广播Invite请求");
+
             responseAck(serverTransaction, Response.TRYING);
 
             String contentString = new String(serverTransaction.getRequest().getRawContent());
+            logger.info("[received invite] dev:{} --> server:\n{}\n",device.getDeviceId(),contentString);
             // jainSip不支持y=字段, 移除移除以解析。
             String substring = contentString;
             String ssrc = "0000000404";
@@ -844,7 +846,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
             String username = sdp.getOrigin().getUsername();
             String addressStr = sdp.getOrigin().getAddress();
             logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}", username, addressStr, port, ssrc);
-
+            // todo 向zlm服务器申请推流转发通道
         } else {
             logger.warn("来自无效设备/平台的请求");
             responseAck(serverTransaction, Response.BAD_REQUEST);

+ 4 - 1
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java

@@ -46,7 +46,10 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
     public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
         try {
             String channelId = getText(rootElement, "DeviceID");
-            String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + device.getDeviceId() + channelId;
+            logger.info("[sip received] broadcast response from {}",device.getDeviceId());
+            // fix 修改key 取消channelId的key拼接
+            String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + device.getDeviceId();
+
             ServerTransaction serverTransaction = getServerTransaction(evt);
             // 回复200 OK
             responseAck(serverTransaction, Response.OK);

+ 6 - 0
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java

@@ -645,7 +645,10 @@ public class MediaServerServiceImpl implements IMediaServerService {
 
     @Override
     public void updateMediaServerKeepalive(String mediaServerId, JSONObject data) {
+        // fix 无法更新连接时进行重连
         MediaServerItem mediaServerItem = getOne(mediaServerId);
+        JSONObject mediaServerConfig = zlmresTfulUtils.getMediaServerConfig(mediaServerItem);
+        ZLMServerConfig zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
         if (mediaServerItem == null) {
             // 缓存不存在,从数据库查询,如果数据库不存在则是错误的
             MediaServerItem mediaServerItemFromDatabase = getOneFromDatabase(mediaServerId);
@@ -659,8 +662,11 @@ public class MediaServerServiceImpl implements IMediaServerService {
             if (mediaServerItem == null) {
                 // zlm连接重试
                 logger.warn("[更新ZLM 保活信息]失败,未找到流媒体信息");
+
                 return;
             }
+            publisher.zlmOfflineEventPublish(mediaServerItem.getId());
+            zlmServerOnline(zlmServerConfig);
         }
         final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId();
         dynamicTask.stop(zlmKeepaliveKey);

+ 1 - 0
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/broadCast/BroadCast.java

@@ -28,6 +28,7 @@ public class BroadCast {
     public WVPResult start(@RequestParam String deviceId,@RequestParam String channelId){
         WVPResult result = new WVPResult<>();
         // todo 完成 broaderCast 信息发送
+
         return result;
     }
 }

+ 7 - 9
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java

@@ -25,12 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import com.alibaba.fastjson.JSONObject;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
@@ -207,12 +202,13 @@ public class PlayController {
 
 	@Operation(summary = "语音广播命令")
 	@Parameter(name = "deviceId", description = "设备国标编号", required = true)
-    @GetMapping("/broadcast/{deviceId}")
-    @PostMapping("/broadcast/{deviceId}")
-    public DeferredResult<String> broadcastApi(@PathVariable String deviceId) {
+    @GetMapping("/broadcast")
+//    @PostMapping("/broadcast/{deviceId}")
+    public DeferredResult<String> broadcastApi(@RequestParam String deviceId) {
         if (logger.isDebugEnabled()) {
             logger.debug("语音广播API调用");
         }
+
         Device device = storager.queryVideoDevice(deviceId);
 		DeferredResult<String> result = new DeferredResult<>(3 * 1000L);
 		String key  = DeferredResultHolder.CALLBACK_CMD_BROADCAST + deviceId;
@@ -236,6 +232,7 @@ public class PlayController {
 			resultHolder.invokeResult(msg);
 			return result;
 		}
+		// 发送广播命令
 		try {
 			cmder.audioBroadcastCmd(device, (event) -> {
 				RequestMessage msg = new RequestMessage();
@@ -249,6 +246,7 @@ public class PlayController {
 				msg.setData(json);
 				resultHolder.invokeResult(msg);
 			});
+			// 收到broadcast回复后,去向zlm申请推流端口
 		} catch (InvalidArgumentException | SipException | ParseException e) {
 			logger.error("[命令发送失败] 语音广播: {}", e.getMessage());
 			throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());

+ 3 - 3
src/main/resources/application.yml

@@ -123,13 +123,13 @@ media:
     # [必须修改] zlm服务器唯一id,用于触发hook时区别是哪台服务器,general.mediaServerId
     id: your_server_id
     # [必须修改] zlm服务器的内网IP
-    ip: 192.168.1.99
+    ip: 192.168.1.211
     # [可选] 返回流地址时的ip,置空使用 media.ip
-    stream-ip: szgpay.ticp.net
+    stream-ip: 192.168.1.211
     #stream-ip: 192.168.1.203
     #stream-ip: 113.88.194.58
     # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
-    sdp-ip: szgpay.ticp.net
+    sdp-ip: 192.168.1.211
     #sdp-ip: 192.168.1.203
     #sdp-ip: 113.88.194.58
     # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip

+ 6 - 3
web_src/src/components/common/microphone.vue

@@ -53,13 +53,16 @@ export default {
         [err,stream] = await handle(this.queryMediaStream());
         if(err){
           this.$message.error('获取音频设备失败!');
-          return;
+          // return;
         }
         this.isQueryAllowAudio = true;
+        await this.sendBroaderCast();
+
       }
       if(!this.isQueryAllowAudio){
         return this.$message.error('无法获取音频!');
       }
+
       this.isRecording = true;
       // 通知设备开始推流
       // 开始录音并推送音频至 wvp 服务器 || 或者推送至 zlm
@@ -71,8 +74,8 @@ export default {
     },
     // 通知设备开启推流
     async sendBroaderCast(){
-      let url = `/api/broader`
-      url+=`?devId=${this.deviceId}&channel=${this.channelId}`;
+      let url = `/api/play/broadcast`
+      url+=`?deviceId=${this.deviceId}&channel=${this.channelId}`;
       let [err,res] = await handle(this.$axios({
         method: 'get',
         url: url