优化国标级联发流并发能力
This commit is contained in:
@@ -7,10 +7,12 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sip.*;
|
||||
import javax.sip.DialogTerminatedEvent;
|
||||
import javax.sip.ResponseEvent;
|
||||
import javax.sip.TimeoutEvent;
|
||||
import javax.sip.TransactionTerminatedEvent;
|
||||
import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -29,6 +31,7 @@ public class SipSubscribe {
|
||||
private Map<String, SipSubscribe.Event> okSubscribes = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, Instant> okTimeSubscribes = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, Instant> errorTimeSubscribes = new ConcurrentHashMap<>();
|
||||
|
||||
// @Scheduled(cron="*/5 * * * * ?") //每五秒执行一次
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.record;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @description: 录像查询结束时间
|
||||
* @description: 录像查询结束事件
|
||||
* @author: pan
|
||||
* @data: 2022-02-23
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||
@@ -12,45 +11,31 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.utils.GitUtil;
|
||||
import gov.nist.javax.sip.SIPConstants;
|
||||
import gov.nist.javax.sip.SipProviderImpl;
|
||||
import gov.nist.javax.sip.SipStackImpl;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import gov.nist.javax.sip.message.SIPRequest;
|
||||
import gov.nist.javax.sip.message.SIPResponse;
|
||||
import gov.nist.javax.sip.stack.SIPClientTransaction;
|
||||
import gov.nist.javax.sip.stack.SIPClientTransactionImpl;
|
||||
import gov.nist.javax.sip.stack.SIPDialog;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.sip.*;
|
||||
import javax.sip.address.Address;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.header.*;
|
||||
import javax.sip.message.Message;
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.ResponseEvent;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.SipFactory;
|
||||
import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.message.Request;
|
||||
import javax.sip.message.Response;
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.ParseException;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @description:设备能力接口,用于定义设备的控制、查询能力
|
||||
@@ -183,7 +168,7 @@ public class SIPCommander implements ISIPCommander {
|
||||
public void ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed,
|
||||
int zoomSpeed) throws InvalidArgumentException, SipException, ParseException {
|
||||
String cmdStr = SipUtils.cmdString(leftRight, upDown, inOut, moveSpeed, zoomSpeed);
|
||||
StringBuffer ptzXml = new StringBuffer(200);
|
||||
StringBuilder ptzXml = new StringBuilder(200);
|
||||
String charset = device.getCharset();
|
||||
ptzXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
ptzXml.append("<Control>\r\n");
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
|
||||
@@ -15,15 +14,12 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import gov.nist.javax.sip.SipProviderImpl;
|
||||
import gov.nist.javax.sip.message.MessageFactoryImpl;
|
||||
import gov.nist.javax.sip.message.SIPRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -638,7 +634,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
||||
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||
if (mediaServerItem != null) {
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
|
||||
zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());
|
||||
zlmrtpServerFactory.closeRtpServer(mediaServerItem, sendRtpItem.getStreamId());
|
||||
}
|
||||
SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem);
|
||||
if (byeRequest == null) {
|
||||
|
||||
@@ -10,8 +10,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg;
|
||||
@@ -33,7 +33,8 @@ import javax.sip.header.FromHeader;
|
||||
import javax.sip.header.HeaderAddress;
|
||||
import javax.sip.header.ToHeader;
|
||||
import java.text.ParseException;
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* SIP命令类型: ACK请求
|
||||
@@ -62,6 +63,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
|
||||
@Autowired
|
||||
private ZLMRTPServerFactory zlmrtpServerFactory;
|
||||
|
||||
@Autowired
|
||||
private ZlmHttpHookSubscribe hookSubscribe;
|
||||
|
||||
@Autowired
|
||||
private IMediaServerService mediaServerService;
|
||||
|
||||
@@ -130,8 +134,18 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
|
||||
startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, jsonObject, param, callIdHeader);
|
||||
});
|
||||
}else {
|
||||
JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
|
||||
startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, jsonObject, param, callIdHeader);
|
||||
// 如果是非严格模式,需要关闭端口占用
|
||||
JSONObject startSendRtpStreamResult = null;
|
||||
if (sendRtpItem.getLocalPort() != 0) {
|
||||
if (zlmrtpServerFactory.releasePort(mediaInfo, sendRtpItem.getSsrc())) {
|
||||
startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
|
||||
}
|
||||
}else {
|
||||
startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
|
||||
}
|
||||
if (startSendRtpStreamResult != null) {
|
||||
startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, startSendRtpStreamResult, param, callIdHeader);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void startSendRtpStreamHand(RequestEvent evt, SendRtpItem sendRtpItem, ParentPlatform parentPlatform,
|
||||
|
||||
@@ -45,6 +45,7 @@ import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.util.Random;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
@@ -157,11 +158,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
||||
StreamProxyItem proxyByAppAndStream =null;
|
||||
// 不是通道可能是直播流
|
||||
if (channel != null && gbStream == null) {
|
||||
// if (channel.getStatus() == 0) {
|
||||
// logger.info("通道离线,返回400");
|
||||
// responseAck(request, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
|
||||
// return;
|
||||
// }
|
||||
// 通道存在,发100,TRYING
|
||||
try {
|
||||
responseAck(request, Response.TRYING);
|
||||
@@ -385,7 +381,12 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
||||
} else {
|
||||
content.append("t=0 0\r\n");
|
||||
}
|
||||
content.append("m=video " + sendRtpItem.getLocalPort() + " RTP/AVP 96\r\n");
|
||||
int localPort = sendRtpItem.getLocalPort();
|
||||
if (localPort == 0) {
|
||||
// 非严格模式端口不统一, 增加兼容性,修改为一个不为0的端口
|
||||
localPort = new Random().nextInt(65535) + 1;
|
||||
}
|
||||
content.append("m=video " + localPort + " RTP/AVP 96\r\n");
|
||||
content.append("a=sendonly\r\n");
|
||||
content.append("a=rtpmap:96 PS/90000\r\n");
|
||||
content.append("y=" + sendRtpItem.getSsrc() + "\r\n");
|
||||
@@ -476,9 +477,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
||||
|
||||
// 写入redis, 超时时回复
|
||||
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
||||
MediaServerItem finalMediaServerItem = mediaServerItem;
|
||||
playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> {
|
||||
logger.info("[上级点播]超时, 用户:{}, 通道:{}", username, channelId);
|
||||
redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
|
||||
zlmrtpServerFactory.releasePort(finalMediaServerItem, sendRtpItem.getSsrc());
|
||||
}, null);
|
||||
} else {
|
||||
sendRtpItem.setStreamId(playTransaction.getStream());
|
||||
|
||||
Reference in New Issue
Block a user