修复缓存 bug

以及添加 设备目录查询
This commit is contained in:
shikong 2023-08-22 15:52:08 +08:00
parent 29f1ae38d5
commit 3d4cb4d9e2
7 changed files with 416 additions and 8 deletions

View File

@ -10,4 +10,6 @@ public class CacheUtil {
public static String getKey(String prefix,String... ids){
return StringUtils.joinWith(SEPARATOR, (Object[]) ArrayUtils.addFirst(ids,prefix));
}
public final static String SIP_C_SEQ_PREFIX = "SIP_C_SEQ_";
}

View File

@ -5,14 +5,23 @@ import cn.skcks.docking.gb28181.core.sip.gb28181.constant.GB28181Constant;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@JacksonXmlRootElement(localName = "Query")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class RecordInfoRequestDTO {
private String cmdType;
@Builder.Default
private String cmdType = "RecordInfo";
@JacksonXmlProperty(localName = "SN")
private String sn;
@ -20,9 +29,17 @@ public class RecordInfoRequestDTO {
@JacksonXmlProperty(localName = "DeviceID")
private String deviceId;
@NotNull
@JsonFormat(pattern = DatePattern.UTC_SIMPLE_PATTERN, timezone = GB28181Constant.TIME_ZONE)
private Date startTime;
@JsonFormat(pattern = DatePattern.UTC_SIMPLE_PATTERN, timezone = GB28181Constant.TIME_ZONE)
private Date endTime;
@Builder.Default
@Min(value = 0)
private Integer Secrecy = 0;
@Builder.Default
private String type = "all";
}

View File

@ -101,7 +101,7 @@ public class RegisterRequestProcessor implements MessageProcessor {
log.debug("设备 deviceId => {}, 认证通过", deviceId);
registerDevice(deviceId, device, request, senderIp,remoteInfo);
registerDevice(deviceId, device, request, senderIp, remoteInfo);
}
@SneakyThrows

View File

@ -0,0 +1,360 @@
package cn.skcks.docking.gb28181.core.sip.message.request;
import cn.skcks.docking.gb28181.common.redis.RedisUtil;
import cn.skcks.docking.gb28181.config.sip.SipConfig;
import cn.skcks.docking.gb28181.core.sip.dto.SipTransactionInfo;
import cn.skcks.docking.gb28181.core.sip.gb28181.cache.CacheUtil;
import cn.skcks.docking.gb28181.core.sip.utils.SipUtil;
import cn.skcks.docking.gb28181.orm.mybatis.dynamic.model.DockingDevice;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
import lombok.SneakyThrows;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import javax.sip.InvalidArgumentException;
import javax.sip.PeerUnavailableException;
import javax.sip.SipException;
import javax.sip.SipFactory;
import javax.sip.address.Address;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.message.Request;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@DependsOn({"sipConfig"})
@Component
public class SipRequestBuilder implements ApplicationContextAware {
private static SipConfig sipConfig;
private static SipFactory getSipFactory(){
return SipFactory.getInstance();
}
@SneakyThrows
private static SipURI getSipURI(String id,String address){
return getSipFactory().createAddressFactory().createSipURI(id, address);
}
@SneakyThrows
private static Address getAddress(SipURI uri){
return getSipFactory().createAddressFactory().createAddress(uri);
}
@SneakyThrows
private static FromHeader getFromHeader(Address fromAddress,String fromTag){
return getSipFactory().createHeaderFactory().createFromHeader(fromAddress, fromTag);
}
@SneakyThrows
private static ToHeader getToHeader(Address toAddress,String toTag){
return getSipFactory().createHeaderFactory().createToHeader(toAddress, toTag);
}
@SneakyThrows
private static MaxForwardsHeader getMaxForwardsHeader(int maxForwards){
return getSipFactory().createHeaderFactory().createMaxForwardsHeader(maxForwards);
}
@SneakyThrows
private static List<ViaHeader> getDeviceViaHeaders(DockingDevice device, String viaTag){
ViaHeader viaHeader = getSipFactory().createHeaderFactory().createViaHeader(device.getLocalIp(), sipConfig.getPort(), device.getTransport(), viaTag);
viaHeader.setRPort();
return Collections.singletonList(viaHeader);
}
public static Request createMessageRequest(DockingDevice device, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
Request request = null;
// sip uri
SipURI requestURI = getSipURI(device.getDeviceId(), device.getHostAddress());
// via
List<ViaHeader> viaHeaders = getDeviceViaHeaders(device, viaTag);
// from
SipURI fromSipURI = getSipURI(sipConfig.getId(), sipConfig.getDomain());
Address fromAddress = getAddress(fromSipURI);
FromHeader fromHeader = getFromHeader(fromAddress, fromTag);
// to
SipURI toSipURI = getSipURI(device.getDeviceId(), device.getHostAddress());
Address toAddress = getAddress(toSipURI);
ToHeader toHeader = getToHeader(toAddress, toTag);
// Forwards
MaxForwardsHeader maxForwards = getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = getSipFactory().createHeaderFactory().createCSeqHeader(getCSeq(), Request.MESSAGE);
request = getSipFactory().createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
toHeader, viaHeaders, maxForwards);
request.addHeader(SipUtil.createUserAgentHeader());
ContentTypeHeader contentTypeHeader = getSipFactory().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
request.setContent(content, contentTypeHeader);
return request;
}
public static Request createInviteRequest(DockingDevice device, String channelId, String content, String viaTag, String fromTag, String toTag, String ssrc, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
Request request = null;
// 请求行
SipURI requestLine = getSipURI(channelId, device.getHostAddress());
// via
List<ViaHeader> viaHeaders = getDeviceViaHeaders(device, viaTag);
// from
SipURI fromSipURI = getSipURI(sipConfig.getId(), sipConfig.getDomain());
Address fromAddress = getAddress(fromSipURI);
FromHeader fromHeader = getFromHeader(fromAddress, fromTag); // 必须要有标记否则无法创建会话无法回应ack
// to
SipURI toSipURI = getSipURI(channelId, device.getHostAddress());
Address toAddress = getAddress(toSipURI);
ToHeader toHeader = getToHeader(toAddress, null);
// Forwards
MaxForwardsHeader maxForwards = getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = getSipFactory().createHeaderFactory().createCSeqHeader(getCSeq(), Request.INVITE);
request = getSipFactory().createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards);
request.addHeader(SipUtil.createUserAgentHeader());
Address concatAddress = getAddress(getSipURI(sipConfig.getId(), device.getLocalIp() + ":" + sipConfig.getPort()));
// Address concatAddress = getAddress(getSipURI(sipConfig.getId(), device.getHost().getIp()+":"+device.getHost().getPort()));
request.addHeader(getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
// Subject
SubjectHeader subjectHeader = getSipFactory().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0));
request.addHeader(subjectHeader);
ContentTypeHeader contentTypeHeader = getSipFactory().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
request.setContent(content, contentTypeHeader);
return request;
}
public static Request createPlaybackInviteRequest(DockingDevice device, String channelId, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader, String ssrc) throws ParseException, InvalidArgumentException, PeerUnavailableException {
Request request = null;
// 请求行
SipURI requestLine = getSipURI(channelId, device.getHostAddress());
// via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = getSipFactory().createHeaderFactory().createViaHeader(device.getLocalIp(), sipConfig.getPort(), device.getTransport(), viaTag);
viaHeader.setRPort();
viaHeaders.add(viaHeader);
// from
SipURI fromSipURI = getSipURI(sipConfig.getId(), sipConfig.getDomain());
Address fromAddress = getAddress(fromSipURI);
FromHeader fromHeader = getFromHeader(fromAddress, fromTag); // 必须要有标记否则无法创建会话无法回应ack
// to
SipURI toSipURI = getSipURI(channelId, device.getHostAddress());
Address toAddress = getAddress(toSipURI);
ToHeader toHeader = getToHeader(toAddress, null);
// Forwards
MaxForwardsHeader maxForwards = getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = getSipFactory().createHeaderFactory().createCSeqHeader(getCSeq(), Request.INVITE);
request = getSipFactory().createMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards);
Address concatAddress = getAddress(getSipURI(sipConfig.getId(), device.getLocalIp() + ":" + sipConfig.getPort()));
// Address concatAddress = getAddress(getSipURI(sipConfig.getId(), device.getHost().getIp()+":"+device.getHost().getPort()));
request.addHeader(getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
request.addHeader(SipUtil.createUserAgentHeader());
// Subject
SubjectHeader subjectHeader = getSipFactory().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", channelId, ssrc, sipConfig.getId(), 0));
request.addHeader(subjectHeader);
ContentTypeHeader contentTypeHeader = getSipFactory().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
request.setContent(content, contentTypeHeader);
return request;
}
public static Request createByteRequest(DockingDevice device, String channelId, SipTransactionInfo transactionInfo) throws ParseException, InvalidArgumentException, PeerUnavailableException {
Request request = null;
// 请求行
SipURI requestLine = getSipURI(channelId, device.getHostAddress());
// via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = getSipFactory().createHeaderFactory().createViaHeader(device.getLocalIp(), sipConfig.getPort(), device.getTransport(), SipUtil.generateViaTag());
viaHeaders.add(viaHeader);
// from
SipURI fromSipURI = getSipURI(sipConfig.getId(), sipConfig.getDomain());
Address fromAddress = getAddress(fromSipURI);
FromHeader fromHeader = getFromHeader(fromAddress, transactionInfo.getFromTag());
// to
SipURI toSipURI = getSipURI(channelId, device.getHostAddress());
Address toAddress = getAddress(toSipURI);
ToHeader toHeader = getToHeader(toAddress, transactionInfo.getToTag());
// Forwards
MaxForwardsHeader maxForwards = getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = getSipFactory().createHeaderFactory().createCSeqHeader(getCSeq(), Request.BYE);
CallIdHeader callIdHeader = getSipFactory().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId());
request = getSipFactory().createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards);
request.addHeader(SipUtil.createUserAgentHeader());
Address concatAddress = getAddress(getSipURI(sipConfig.getId(), device.getLocalIp() + ":" + sipConfig.getPort()));
request.addHeader(getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
request.addHeader(SipUtil.createUserAgentHeader());
return request;
}
public static Request createSubscribeRequest(DockingDevice device, String content, SIPRequest requestOld, Integer expires, String event, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
Request request = null;
// sipuri
SipURI requestURI = getSipURI(device.getDeviceId(), device.getHostAddress());
// via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = getSipFactory().createHeaderFactory().createViaHeader(device.getLocalIp(), sipConfig.getPort(),
device.getTransport(), SipUtil.generateViaTag());
viaHeader.setRPort();
viaHeaders.add(viaHeader);
// from
SipURI fromSipURI = getSipURI(sipConfig.getId(), sipConfig.getDomain());
Address fromAddress = getAddress(fromSipURI);
FromHeader fromHeader = getFromHeader(fromAddress, requestOld == null ? SipUtil.generateFromTag() : requestOld.getFromTag());
// to
SipURI toSipURI = getSipURI(device.getDeviceId(), device.getHostAddress());
Address toAddress = getAddress(toSipURI);
ToHeader toHeader = getToHeader(toAddress, requestOld == null ? null : requestOld.getToTag());
// Forwards
MaxForwardsHeader maxForwards = getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = getSipFactory().createHeaderFactory().createCSeqHeader(getCSeq(), Request.SUBSCRIBE);
request = getSipFactory().createMessageFactory().createRequest(requestURI, Request.SUBSCRIBE, callIdHeader, cSeqHeader, fromHeader,
toHeader, viaHeaders, maxForwards);
Address concatAddress = getAddress(getSipURI(sipConfig.getId(), device.getLocalIp() + ":" + sipConfig.getPort()));
request.addHeader(getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
// Expires
ExpiresHeader expireHeader = getSipFactory().createHeaderFactory().createExpiresHeader(expires);
request.addHeader(expireHeader);
// Event
EventHeader eventHeader = getSipFactory().createHeaderFactory().createEventHeader(event);
int random = (int) Math.floor(Math.random() * 10000);
eventHeader.setEventId(String.valueOf(random));
request.addHeader(eventHeader);
ContentTypeHeader contentTypeHeader = getSipFactory().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
request.setContent(content, contentTypeHeader);
request.addHeader(SipUtil.createUserAgentHeader());
return request;
}
public static SIPRequest createInfoRequest(DockingDevice device, String channelId, String content, SipTransactionInfo transactionInfo)
throws SipException, ParseException, InvalidArgumentException {
if (device == null || transactionInfo == null) {
return null;
}
SIPRequest request = null;
// 请求行
SipURI requestLine = getSipURI(channelId, device.getHostAddress());
// via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = getSipFactory().createHeaderFactory().createViaHeader(device.getLocalIp(), sipConfig.getPort(), device.getTransport(), SipUtil.generateViaTag());
viaHeaders.add(viaHeader);
// from
SipURI fromSipURI = getSipURI(sipConfig.getId(), sipConfig.getDomain());
Address fromAddress = getAddress(fromSipURI);
FromHeader fromHeader = getFromHeader(fromAddress, transactionInfo.getFromTag());
// to
SipURI toSipURI = getSipURI(channelId, device.getHostAddress());
Address toAddress = getAddress(toSipURI);
ToHeader toHeader = getToHeader(toAddress, transactionInfo.getToTag());
// Forwards
MaxForwardsHeader maxForwards = getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = getSipFactory().createHeaderFactory().createCSeqHeader(getCSeq(), Request.INFO);
CallIdHeader callIdHeader = getSipFactory().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId());
request = (SIPRequest) getSipFactory().createMessageFactory().createRequest(requestLine, Request.INFO, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwards);
request.addHeader(SipUtil.createUserAgentHeader());
Address concatAddress = getAddress(getSipURI(sipConfig.getId(), device.getLocalIp() + ":" + sipConfig.getPort()));
request.addHeader(getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
request.addHeader(SipUtil.createUserAgentHeader());
if (content != null) {
ContentTypeHeader contentTypeHeader = getSipFactory().createHeaderFactory().createContentTypeHeader("Application",
"MANSRTSP");
request.setContent(content, contentTypeHeader);
}
return request;
}
public static Request createAckRequest(String localIp, SipURI sipURI, SIPResponse sipResponse) throws ParseException, InvalidArgumentException, PeerUnavailableException {
// via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = getSipFactory().createHeaderFactory().createViaHeader(localIp, sipConfig.getPort(), sipResponse.getTopmostViaHeader().getTransport(), SipUtil.generateViaTag());
viaHeaders.add(viaHeader);
// Forwards
MaxForwardsHeader maxForwards = getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
// ceq
CSeqHeader cSeqHeader = getSipFactory().createHeaderFactory().createCSeqHeader(sipResponse.getCSeqHeader().getSeqNumber(), Request.ACK);
Request request = getSipFactory().createMessageFactory().createRequest(sipURI, Request.ACK, sipResponse.getCallIdHeader(), cSeqHeader, sipResponse.getFromHeader(), sipResponse.getToHeader(), viaHeaders, maxForwards);
request.addHeader(SipUtil.createUserAgentHeader());
Address concatAddress = getAddress(getSipURI(sipConfig.getId(), localIp + ":" + sipConfig.getPort()));
request.addHeader(getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
request.addHeader(SipUtil.createUserAgentHeader());
return request;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
sipConfig = applicationContext.getBean(SipConfig.class);
}
public static long getCSeq() {
String key = CacheUtil.getKey(CacheUtil.SIP_C_SEQ_PREFIX,sipConfig.getId());
long result = 1L;
if(RedisUtil.KeyOps.hasKey(key)){
try {
result = RedisUtil.StringOps.incrBy(key,1L);
} finally {
if (result > Integer.MAX_VALUE) {
RedisUtil.StringOps.set(key, String.valueOf(1L));
result = 1L;
}
}
} else {
RedisUtil.StringOps.set(key, String.valueOf(result));
}
return result;
}
}

View File

@ -63,8 +63,8 @@ public class DockingDeviceService {
}),()->{
dockingDeviceMapper.insert(device);
});
getDevice(deviceId);
deviceCacheService.removeDevice(deviceId);
deviceCacheService.cacheDevice(deviceId,device);
onlineCacheService.setOnline(deviceId, DeviceConstant.KEEP_ALIVE_INTERVAL * 3, DeviceConstant.UNIT);
setTransaction(deviceId, response);
}

View File

@ -1,13 +1,23 @@
package cn.skcks.docking.gb28181.service.record;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.skcks.docking.gb28181.common.xml.XmlUtils;
import cn.skcks.docking.gb28181.core.sip.message.processor.record.dto.RecordInfoRequestDTO;
import cn.skcks.docking.gb28181.core.sip.message.request.SipRequestBuilder;
import cn.skcks.docking.gb28181.core.sip.message.sender.SipMessageSender;
import cn.skcks.docking.gb28181.core.sip.service.SipService;
import cn.skcks.docking.gb28181.core.sip.utils.SipUtil;
import cn.skcks.docking.gb28181.orm.mybatis.dynamic.model.DockingDevice;
import cn.skcks.docking.gb28181.service.docking.device.DockingDeviceService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.sip.SipProvider;
import javax.sip.header.CallIdHeader;
import javax.sip.message.Request;
@Slf4j
@Service
@ -15,10 +25,12 @@ import javax.sip.SipProvider;
public class RecordService {
private final DockingDeviceService deviceService;
private final SipService sipService;
private final SipMessageSender sender;
@SneakyThrows
public void requestRecordInfo(String deviceId){
DockingDevice device = deviceService.getDevice(deviceId);
if(device == null){
if (device == null) {
log.info("未能找到 编码为 => {} 的设备", deviceId);
return;
}
@ -26,6 +38,19 @@ public class RecordService {
String transport = device.getTransport();
String senderIp = device.getLocalIp();
SipProvider provider = sipService.getProvider(transport, senderIp);
log.info("provider => {}", provider);
CallIdHeader callId = provider.getNewCallId();
RecordInfoRequestDTO dto = RecordInfoRequestDTO.builder()
.deviceId(deviceId)
.startTime(DateUtil.beginOfDay(DateUtil.date()))
.endTime(DateUtil.endOfDay(DateUtil.date()))
.sn(String.valueOf((int)(Math.random() * 9 + 1) * 100000))
.build();
Request request = SipRequestBuilder.createMessageRequest(device,
XmlUtils.toXml(dto),
SipUtil.generateViaTag(),
SipUtil.generateFromTag(),
null,
callId);
sender.send(senderIp, request);
}
}

View File

@ -1,6 +1,7 @@
package cn.skcks.docking.gb28181.core.sip.message.dto;
import cn.hutool.core.date.DateUtil;
import cn.skcks.docking.gb28181.common.json.JsonUtils;
import cn.skcks.docking.gb28181.common.xml.XmlUtils;
import cn.skcks.docking.gb28181.core.sip.message.processor.record.dto.RecordInfoRequestDTO;
import lombok.extern.slf4j.Slf4j;
@ -14,8 +15,11 @@ public class DTOTest {
dto.setCmdType("RecordInfo");
dto.setDeviceId("44050100001310000006");
dto.setSn("66666");
dto.setStartTime(DateUtil.date());
dto.setStartTime(DateUtil.beginOfDay(DateUtil.date()));
dto.setEndTime(DateUtil.date());
log.info("\n{}", XmlUtils.toXml(dto));
String xml = XmlUtils.toXml(dto);
log.info("\n{}", xml);
log.info("{}", XmlUtils.parse(xml,RecordInfoRequestDTO.class));
log.info("\n{}", JsonUtils.toJson(dto));
}
}