尝试解决内存溢出,并使用多线程提高性能

This commit is contained in:
swwheihei
2020-07-16 17:31:41 +08:00
parent d8eeb70707
commit c96ab05d7d
14 changed files with 1137 additions and 242 deletions

View File

@@ -2,115 +2,113 @@ package com.genersoft.iot.vmp.gb28181;
import java.text.ParseException;
import java.util.Properties;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.sip.DialogTerminatedEvent;
import javax.sip.IOExceptionEvent;
import javax.sip.ListeningPoint;
import javax.sip.PeerUnavailableException;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipFactory;
import javax.sip.SipListener;
import javax.sip.SipProvider;
import javax.sip.SipStack;
import javax.sip.TimeoutEvent;
import javax.sip.TransactionAlreadyExistsException;
import javax.sip.TransactionTerminatedEvent;
import javax.sip.TransactionUnavailableException;
import javax.sip.address.AddressFactory;
import javax.sip.header.HeaderFactory;
import javax.sip.header.ViaHeader;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
import gov.nist.javax.sip.SipStackImpl;
@Component
public class SipLayer implements SipListener, Runnable {
public class SipLayer implements SipListener {
private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
@Autowired
private SipConfig sipConfig;
private SipProvider tcpSipProvider;
private SipProvider udpSipProvider;
@Autowired
private SIPProcessorFactory processorFactory;
private SipStack sipStack;
private AddressFactory addressFactory;
private HeaderFactory headerFactory;
private MessageFactory messageFactory;
private SipFactory sipFactory;
@PostConstruct
/**
* 消息处理器线程池
*/
private ThreadPoolExecutor processThreadPool;
@Bean("initSipServer")
@DependsOn("allOffline")
private void initSipServer() {
Thread thread = new Thread(this);
thread.setDaemon(true);
thread.setName("sip server thread start");
thread.start();
int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<Runnable>(10000);
processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
0L,TimeUnit.MILLISECONDS,processQueue,
new ThreadPoolExecutor.CallerRunsPolicy());
}
@Override
public void run() {
SipFactory sipFactory = SipFactory.getInstance();
@Bean("sipFactory")
@DependsOn("initSipServer")
private SipFactory createSipFactory() {
sipFactory = SipFactory.getInstance();
sipFactory.setPathName("gov.nist");
try {
headerFactory = sipFactory.createHeaderFactory();
addressFactory = sipFactory.createAddressFactory();
messageFactory = sipFactory.createMessageFactory();
Properties properties = new Properties();
properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp());
properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
/**
* sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =
* 0; public static final int TRACE_MESSAGES = 16; public static final int
* TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32;
*/
properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");
sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
startTcpListener();
startUdpListener();
} catch (Exception e) {
logger.error("Sip Server 启动失败! port {" + sipConfig.getSipPort() + "}");
e.printStackTrace();
}
logger.info("Sip Server 启动成功 port {" + sipConfig.getSipPort() + "}");
return sipFactory;
}
@Bean("sipStack")
@DependsOn({"initSipServer", "sipFactory"})
private SipStack createSipStack() throws PeerUnavailableException {
Properties properties = new Properties();
properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp());
properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
/**
* sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =
* 0; public static final int TRACE_MESSAGES = 16; public static final int
* TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32;
*/
properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0");
properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");
sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
return sipStack;
}
private void startTcpListener() throws Exception {
ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(),
"TCP");
tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
@Bean("tcpSipProvider")
@DependsOn("sipStack")
private SipProvider startTcpListener() throws Exception {
ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "TCP");
SipProvider tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
tcpSipProvider.addSipListener(this);
logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getSipPort() + "}");
return tcpSipProvider;
}
private void startUdpListener() throws Exception {
ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(),
"UDP");
udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
@Bean("udpSipProvider")
@DependsOn("sipStack")
private SipProvider startUdpListener() throws Exception {
ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP");
SipProvider udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
udpSipProvider.addSipListener(this);
logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getSipPort() + "}");
return udpSipProvider;
}
/**
@@ -119,8 +117,10 @@ public class SipLayer implements SipListener, Runnable {
*/
@Override
public void processRequest(RequestEvent evt) {
ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt);
processor.process(evt, this);
// 由于jainsip是单线程程序为提高性能并发处理
processThreadPool.execute(() -> {
processorFactory.createRequestProcessor(evt).process();
});
}
@Override
@@ -212,51 +212,4 @@ public class SipLayer implements SipListener, Runnable {
}
public ServerTransaction getServerTransaction(RequestEvent evt) {
Request request = evt.getRequest();
ServerTransaction serverTransaction = evt.getServerTransaction();
// 判断TCP还是UDP
boolean isTcp = false;
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
String transport = reqViaHeader.getTransport();
if (transport.equals("TCP")) {
isTcp = true;
}
if (serverTransaction == null) {
try {
if (isTcp) {
serverTransaction = tcpSipProvider.getNewServerTransaction(request);
} else {
serverTransaction = udpSipProvider.getNewServerTransaction(request);
}
} catch (TransactionAlreadyExistsException e) {
e.printStackTrace();
} catch (TransactionUnavailableException e) {
e.printStackTrace();
}
}
return serverTransaction;
}
public AddressFactory getAddressFactory() {
return addressFactory;
}
public HeaderFactory getHeaderFactory() {
return headerFactory;
}
public MessageFactory getMessageFactory() {
return messageFactory;
}
public SipProvider getTcpSipProvider() {
return tcpSipProvider;
}
public SipProvider getUdpSipProvider() {
return udpSipProvider;
}
}

View File

@@ -2,13 +2,23 @@ package com.genersoft.iot.vmp.gb28181.transmit;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.SipProvider;
import javax.sip.header.CSeqHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;
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.stereotype.Component;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;
import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.AckRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.ByeRequestProcessor;
@@ -23,6 +33,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.impl.ByeResponseProcessor
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.CancelResponseProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.InviteResponseProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcessor;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
/**
* @Description:TODO(这里用一句话描述这个类的作用)
@@ -32,29 +44,31 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcess
@Component
public class SIPProcessorFactory {
@Autowired
private InviteRequestProcessor inviteRequestProcessor;
private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
@Autowired
private RegisterRequestProcessor registerRequestProcessor;
private SipConfig sipConfig;
@Autowired
private SubscribeRequestProcessor subscribeRequestProcessor;
private RegisterLogicHandler handler;
@Autowired
private AckRequestProcessor ackRequestProcessor;
private IVideoManagerStorager storager;
@Autowired
private ByeRequestProcessor byeRequestProcessor;
private EventPublisher publisher;
@Autowired
private CancelRequestProcessor cancelRequestProcessor;
private SIPCommander cmder;
@Autowired
private MessageRequestProcessor messageRequestProcessor;
private RedisUtil redis;
@Autowired
private OtherRequestProcessor otherRequestProcessor;
private DeferredResultHolder deferredResultHolder;
@Autowired
private DeviceOffLineDetector offLineDetector;
@Autowired
private InviteResponseProcessor inviteResponseProcessor;
@@ -68,27 +82,64 @@ public class SIPProcessorFactory {
@Autowired
private OtherResponseProcessor otherResponseProcessor;
@Autowired
@Qualifier(value="tcpSipProvider")
private SipProvider tcpSipProvider;
@Autowired
@Qualifier(value="udpSipProvider")
private SipProvider udpSipProvider;
public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) {
Request request = evt.getRequest();
String method = request.getMethod();
logger.info("接收到消息:"+request.getMethod());
if (Request.INVITE.equals(method)) {
return inviteRequestProcessor;
InviteRequestProcessor processor = new InviteRequestProcessor();
processor.setRequestEvent(evt);
processor.setTcpSipProvider(tcpSipProvider);
processor.setUdpSipProvider(udpSipProvider);
return processor;
} else if (Request.REGISTER.equals(method)) {
return registerRequestProcessor;
RegisterRequestProcessor processor = new RegisterRequestProcessor();
processor.setRequestEvent(evt);
processor.setTcpSipProvider(tcpSipProvider);
processor.setUdpSipProvider(udpSipProvider);
processor.setHandler(handler);
processor.setPublisher(publisher);
processor.setSipConfig(sipConfig);
processor.setVideoManagerStorager(storager);
return processor;
} else if (Request.SUBSCRIBE.equals(method)) {
return subscribeRequestProcessor;
SubscribeRequestProcessor processor = new SubscribeRequestProcessor();
processor.setRequestEvent(evt);
return processor;
} else if (Request.ACK.equals(method)) {
return ackRequestProcessor;
AckRequestProcessor processor = new AckRequestProcessor();
processor.setRequestEvent(evt);
return processor;
} else if (Request.BYE.equals(method)) {
return byeRequestProcessor;
ByeRequestProcessor processor = new ByeRequestProcessor();
processor.setRequestEvent(evt);
return processor;
} else if (Request.CANCEL.equals(method)) {
return cancelRequestProcessor;
CancelRequestProcessor processor = new CancelRequestProcessor();
processor.setRequestEvent(evt);
return processor;
} else if (Request.MESSAGE.equals(method)) {
return messageRequestProcessor;
MessageRequestProcessor processor = new MessageRequestProcessor();
processor.setRequestEvent(evt);
processor.setTcpSipProvider(tcpSipProvider);
processor.setUdpSipProvider(udpSipProvider);
processor.setPublisher(publisher);
processor.setRedis(redis);
processor.setDeferredResultHolder(deferredResultHolder);
processor.setOffLineDetector(offLineDetector);
processor.setCmder(cmder);
processor.setStorager(storager);
return processor;
} else {
return otherRequestProcessor;
return new OtherRequestProcessor();
}
}

View File

@@ -1,9 +1,5 @@
package com.genersoft.iot.vmp.gb28181.transmit.request;
import javax.sip.RequestEvent;
import com.genersoft.iot.vmp.gb28181.SipLayer;
/**
* @Description:处理接收IPCamera发来的SIP协议请求消息
* @author: swwheihei
@@ -11,6 +7,6 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
*/
public interface ISIPRequestProcessor {
public void process(RequestEvent evt, SipLayer layer);
public void process();
}

View File

@@ -0,0 +1,127 @@
package com.genersoft.iot.vmp.gb28181.transmit.request;
import javax.sip.PeerUnavailableException;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipFactory;
import javax.sip.SipProvider;
import javax.sip.TransactionAlreadyExistsException;
import javax.sip.TransactionUnavailableException;
import javax.sip.address.AddressFactory;
import javax.sip.header.HeaderFactory;
import javax.sip.header.ViaHeader;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import gov.nist.javax.sip.SipStackImpl;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.stack.SIPServerTransaction;
/**
* @Description:处理接收IPCamera发来的SIP协议请求消息
* @author: songww
* @date: 2020年5月3日 下午4:42:22
*/
public abstract class SIPRequestAbstractProcessor implements ISIPRequestProcessor {
protected RequestEvent evt;
private SipProvider tcpSipProvider;
private SipProvider udpSipProvider;
@Override
public void process() {
this.process(evt);
}
public abstract void process(RequestEvent evt);
public ServerTransaction getServerTransaction(RequestEvent evt) {
Request request = evt.getRequest();
ServerTransaction serverTransaction = evt.getServerTransaction();
// 判断TCP还是UDP
boolean isTcp = false;
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
String transport = reqViaHeader.getTransport();
if (transport.equals("TCP")) {
isTcp = true;
}
if (serverTransaction == null) {
try {
if (isTcp) {
SipStackImpl stack = (SipStackImpl)tcpSipProvider.getSipStack();
serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
if (serverTransaction == null) {
serverTransaction = tcpSipProvider.getNewServerTransaction(request);
}
} else {
SipStackImpl stack = (SipStackImpl)udpSipProvider.getSipStack();
serverTransaction = (SIPServerTransaction) stack.findTransaction((SIPRequest)request, true);
if (serverTransaction == null) {
serverTransaction = udpSipProvider.getNewServerTransaction(request);
}
}
} catch (TransactionAlreadyExistsException e) {
e.printStackTrace();
} catch (TransactionUnavailableException e) {
e.printStackTrace();
}
}
return serverTransaction;
}
public AddressFactory getAddressFactory() {
try {
return SipFactory.getInstance().createAddressFactory();
} catch (PeerUnavailableException e) {
e.printStackTrace();
}
return null;
}
public HeaderFactory getHeaderFactory() {
try {
return SipFactory.getInstance().createHeaderFactory();
} catch (PeerUnavailableException e) {
e.printStackTrace();
}
return null;
}
public MessageFactory getMessageFactory() {
try {
return SipFactory.getInstance().createMessageFactory();
} catch (PeerUnavailableException e) {
e.printStackTrace();
}
return null;
}
public RequestEvent getRequestEvent() {
return evt;
}
public void setRequestEvent(RequestEvent evt) {
this.evt = evt;
}
public SipProvider getTcpSipProvider() {
return tcpSipProvider;
}
public void setTcpSipProvider(SipProvider tcpSipProvider) {
this.tcpSipProvider = tcpSipProvider;
}
public SipProvider getUdpSipProvider() {
return udpSipProvider;
}
public void setUdpSipProvider(SipProvider udpSipProvider) {
this.udpSipProvider = udpSipProvider;
}
}

View File

@@ -3,14 +3,10 @@ package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
import javax.sip.Dialog;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipException;
import javax.sip.message.Request;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
import gov.nist.javax.sip.header.CSeq;
@@ -19,8 +15,7 @@ import gov.nist.javax.sip.header.CSeq;
* @author: swwheihei
* @date: 2020年5月3日 下午5:31:45
*/
@Component
public class AckRequestProcessor implements ISIPRequestProcessor {
public class AckRequestProcessor extends SIPRequestAbstractProcessor {
/**
* 处理 ACK请求
@@ -31,7 +26,7 @@ public class AckRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer) {
public void process(RequestEvent evt) {
Request request = evt.getRequest();
Dialog dialog = evt.getDialog();
try {

View File

@@ -1,20 +1,15 @@
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
/**
* @Description: BYE请求处理器
* @author: swwheihei
* @date: 2020年5月3日 下午5:32:05
*/
@Component
public class ByeRequestProcessor implements ISIPRequestProcessor {
public class ByeRequestProcessor extends SIPRequestAbstractProcessor {
/**
* 处理BYE请求
@@ -25,8 +20,8 @@ public class ByeRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer) {
// TODO Auto-generated method stub
public void process(RequestEvent evt) {
// TODO 优先级99 Bye Request消息实现此消息一般为级联消息上级给下级发送视频停止指令
}

View File

@@ -1,20 +1,15 @@
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
/**
* @Description:CANCEL请求处理器
* @author: swwheihei
* @date: 2020年5月3日 下午5:32:23
*/
@Component
public class CancelRequestProcessor implements ISIPRequestProcessor {
public class CancelRequestProcessor extends SIPRequestAbstractProcessor {
/**
* 处理CANCEL请求
@@ -25,8 +20,8 @@ public class CancelRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer) {
// TODO Auto-generated method stub
public void process(RequestEvent evt) {
// TODO 优先级99 Cancel Request消息实现此消息一般为级联消息上级给下级发送请求取消指令
}

View File

@@ -1,20 +1,15 @@
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
/**
* @Description:处理INVITE请求
* @author: swwheihei
* @date: 2020年5月3日 下午4:43:52
*/
@Component
public class InviteRequestProcessor implements ISIPRequestProcessor {
public class InviteRequestProcessor extends SIPRequestAbstractProcessor {
/**
* 处理invite请求
@@ -23,8 +18,8 @@ public class InviteRequestProcessor implements ISIPRequestProcessor {
* 请求消息
*/
@Override
public void process(RequestEvent evt, SipLayer layer) {
// TODO Auto-generated method stub
public void process(RequestEvent evt) {
// TODO 优先级99 Invite Request消息实现此消息一般为级联消息上级给下级发送请求视频指令
// Request request = requestEvent.getRequest();
//
// try {
@@ -45,7 +40,6 @@ public class InviteRequestProcessor implements ISIPRequestProcessor {
// Via via = (Via) headerFactory.createViaHeader(SIPMain.ip, SIPMain.port, "UDP",
// callerVia.getBranch() + "sipphone");
//
// // FIXME 需要测试是否能够通过设置VIA头域来修改VIA头域值
// cliReq.removeHeader(Via.NAME);
// cliReq.addHeader(via);
//

View File

@@ -10,7 +10,6 @@ import java.util.Map;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipException;
import javax.sip.message.Request;
import javax.sip.message.Response;
@@ -22,10 +21,8 @@ import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
@@ -35,7 +32,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
@@ -46,38 +43,28 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
* @author: swwheihei
* @date: 2020年5月3日 下午5:32:41
*/
@Component
public class MessageRequestProcessor implements ISIPRequestProcessor {
public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
private final static Logger logger = LoggerFactory.getLogger(MessageRequestProcessor.class);
private ServerTransaction transaction;
private SipLayer layer;
@Autowired
private SIPCommander cmder;
@Autowired
private IVideoManagerStorager storager;
@Autowired
private EventPublisher publisher;
@Autowired
private RedisUtil redis;
@Autowired
private DeferredResultHolder deferredResultHolder;
@Autowired
private DeviceOffLineDetector offLineDetector;
private final static String CACHE_RECORDINFO_KEY = "CACHE_RECORDINFO_";
private static final String MESSAGE_KEEP_ALIVE = "Keepalive";
private static final String MESSAGE_CONFIG_DOWNLOAD = "ConfigDownload";
private static final String MESSAGE_CATALOG = "Catalog";
private static final String MESSAGE_DEVICE_INFO = "DeviceInfo";
private static final String MESSAGE_KEEP_ALIVE = "Keepalive";
private static final String MESSAGE_ALARM = "Alarm";
private static final String MESSAGE_RECORD_INFO = "RecordInfo";
// private static final String MESSAGE_BROADCAST = "Broadcast";
@@ -93,23 +80,17 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
* @param transaction
*/
@Override
public void process(RequestEvent evt, SipLayer layer) {
this.layer = layer;
this.transaction = layer.getServerTransaction(evt);
Request request = evt.getRequest();
SAXReader reader = new SAXReader();
reader.setEncoding("gbk");
Document xml;
public void process(RequestEvent evt) {
try {
xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
Element rootElement = xml.getRootElement();
String cmd = rootElement.element("CmdType").getStringValue();
Element rootElement = getRootElement(evt);
String cmd = XmlUtil.getText(rootElement,"CmdType");
if (MESSAGE_KEEP_ALIVE.equals(cmd)) {
logger.info("接收到KeepAlive消息");
processMessageKeepAlive(evt);
} else if (MESSAGE_CONFIG_DOWNLOAD.equals(cmd)) {
logger.info("接收到ConfigDownload消息");
} else if (MESSAGE_CATALOG.equals(cmd)) {
logger.info("接收到Catalog消息");
processMessageCatalogList(evt);
@@ -126,7 +107,6 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
@@ -273,15 +253,11 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
try {
Element rootElement = getRootElement(evt);
String deviceId = XmlUtil.getText(rootElement,"DeviceID");
Request request = evt.getRequest();
Response response = null;
if (offLineDetector.isOnline(deviceId)) {
response = layer.getMessageFactory().createResponse(Response.OK,request);
responseAck(evt);
publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
} else {
response = layer.getMessageFactory().createResponse(Response.BAD_REQUEST,request);
}
transaction.sendResponse(response);
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
e.printStackTrace();
}
@@ -373,6 +349,11 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
}
}
private void responseAck(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
Response response = getMessageFactory().createResponse(Response.OK,evt.getRequest());
getServerTransaction(evt).sendResponse(response);
}
private Element getRootElement(RequestEvent evt) throws DocumentException {
Request request = evt.getRequest();
SAXReader reader = new SAXReader();
@@ -381,4 +362,28 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
return xml.getRootElement();
}
public void setCmder(SIPCommander cmder) {
this.cmder = cmder;
}
public void setStorager(IVideoManagerStorager storager) {
this.storager = storager;
}
public void setPublisher(EventPublisher publisher) {
this.publisher = publisher;
}
public void setRedis(RedisUtil redis) {
this.redis = redis;
}
public void setDeferredResultHolder(DeferredResultHolder deferredResultHolder) {
this.deferredResultHolder = deferredResultHolder;
}
public void setOffLineDetector(DeviceOffLineDetector offLineDetector) {
this.offLineDetector = offLineDetector;
}
}

View File

@@ -1,20 +1,15 @@
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
/**
* @Description:暂不支持的消息请求处理器
* @author: swwheihei
* @date: 2020年5月3日 下午5:32:59
*/
@Component
public class OtherRequestProcessor implements ISIPRequestProcessor {
public class OtherRequestProcessor extends SIPRequestAbstractProcessor {
/**
* <p>Title: process</p>
@@ -25,7 +20,7 @@ public class OtherRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer) {
public void process(RequestEvent evt) {
System.out.println("no support the method! Method:" + evt.getRequest().getMethod());
}

View File

@@ -7,7 +7,6 @@ import java.util.Locale;
import javax.sip.InvalidArgumentException;
import javax.sip.RequestEvent;
import javax.sip.ServerTransaction;
import javax.sip.SipException;
import javax.sip.header.AuthorizationHeader;
import javax.sip.header.ContactHeader;
@@ -17,19 +16,16 @@ import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
import com.genersoft.iot.vmp.gb28181.auth.RegisterLogicHandler;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.Host;
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import gov.nist.javax.sip.address.AddressImpl;
@@ -41,19 +37,14 @@ import gov.nist.javax.sip.header.Expires;
* @author: swwheihei
* @date: 2020年5月3日 下午4:47:25
*/
@Component
public class RegisterRequestProcessor implements ISIPRequestProcessor {
public class RegisterRequestProcessor extends SIPRequestAbstractProcessor {
@Autowired
private SipConfig sipConfig;
@Autowired
private RegisterLogicHandler handler;
@Autowired
private IVideoManagerStorager storager;
@Autowired
private EventPublisher publisher;
/***
@@ -63,7 +54,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor {
* 请求消息
*/
@Override
public void process(RequestEvent evt, SipLayer layer) {
public void process(RequestEvent evt) {
try {
System.out.println("收到注册请求,开始处理");
Request request = evt.getRequest();
@@ -88,14 +79,14 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor {
} else if (!passwordCorrect) {
System.out.println("密码错误 回复401");
}
response = layer.getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
new DigestServerAuthenticationHelper().generateChallenge(layer.getHeaderFactory(), response, sipConfig.getSipDomain());
response = getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
new DigestServerAuthenticationHelper().generateChallenge(getHeaderFactory(), response, sipConfig.getSipDomain());
}
// 携带授权头并且密码正确
else if (passwordCorrect) {
response = layer.getMessageFactory().createResponse(Response.OK, request);
response = getMessageFactory().createResponse(Response.OK, request);
// 添加date头
response.addHeader(layer.getHeaderFactory().createDateHeader(Calendar.getInstance(Locale.ENGLISH)));
response.addHeader(getHeaderFactory().createDateHeader(Calendar.getInstance(Locale.ENGLISH)));
ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME);
// 添加Contact头
response.addHeader(request.getHeader(ContactHeader.NAME));
@@ -141,7 +132,7 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor {
device.setTransport(isTcp ? "TCP" : "UDP");
}
}
layer.getServerTransaction(evt).sendResponse(response);
getServerTransaction(evt).sendResponse(response);
// 注册成功
// 保存到redis
// 下发catelog查询目录
@@ -159,5 +150,21 @@ public class RegisterRequestProcessor implements ISIPRequestProcessor {
}
}
public void setSipConfig(SipConfig sipConfig) {
this.sipConfig = sipConfig;
}
public void setHandler(RegisterLogicHandler handler) {
this.handler = handler;
}
public void setVideoManagerStorager(IVideoManagerStorager storager) {
this.storager = storager;
}
public void setPublisher(EventPublisher publisher) {
this.publisher = publisher;
}
}

View File

@@ -10,18 +10,14 @@ import javax.sip.header.ExpiresHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;
import org.springframework.stereotype.Component;
import com.genersoft.iot.vmp.gb28181.SipLayer;
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.request.SIPRequestAbstractProcessor;
/**
* @Description:SUBSCRIBE请求处理器
* @author: swwheihei
* @date: 2020年5月3日 下午5:31:20
*/
@Component
public class SubscribeRequestProcessor implements ISIPRequestProcessor {
public class SubscribeRequestProcessor extends SIPRequestAbstractProcessor {
/**
* 处理SUBSCRIBE请求
@@ -32,18 +28,18 @@ public class SubscribeRequestProcessor implements ISIPRequestProcessor {
* @param config
*/
@Override
public void process(RequestEvent evt, SipLayer layer) {
public void process(RequestEvent evt) {
Request request = evt.getRequest();
try {
Response response = null;
response = layer.getMessageFactory().createResponse(200, request);
response = getMessageFactory().createResponse(200, request);
if (response != null) {
ExpiresHeader expireHeader = layer.getHeaderFactory().createExpiresHeader(30);
ExpiresHeader expireHeader = getHeaderFactory().createExpiresHeader(30);
response.setExpires(expireHeader);
}
System.out.println("response : " + response.toString());
ServerTransaction transaction = layer.getServerTransaction(evt);
ServerTransaction transaction = getServerTransaction(evt);
if (transaction != null) {
transaction.sendResponse(response);
transaction.terminate();