SipLayer.java 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. package com.genersoft.iot.vmp.gb28181;
  2. import java.text.ParseException;
  3. import java.util.Properties;
  4. import java.util.TooManyListenersException;
  5. import java.util.concurrent.LinkedBlockingQueue;
  6. import java.util.concurrent.ThreadPoolExecutor;
  7. import java.util.concurrent.TimeUnit;
  8. import javax.sip.*;
  9. import javax.sip.header.CallIdHeader;
  10. import javax.sip.message.Response;
  11. import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.context.annotation.Bean;
  16. // import org.springframework.context.annotation.ComponentScan;
  17. import org.springframework.context.annotation.DependsOn;
  18. import org.springframework.stereotype.Component;
  19. import com.genersoft.iot.vmp.conf.SipConfig;
  20. import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
  21. import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
  22. import gov.nist.javax.sip.SipStackImpl;
  23. @Component
  24. public class SipLayer implements SipListener {
  25. private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
  26. @Autowired
  27. private SipConfig sipConfig;
  28. @Autowired
  29. private SIPProcessorFactory processorFactory;
  30. @Autowired
  31. private SipSubscribe sipSubscribe;
  32. private SipStack sipStack;
  33. private SipFactory sipFactory;
  34. /**
  35. * 消息处理器线程池
  36. */
  37. private ThreadPoolExecutor processThreadPool;
  38. @Bean("initSipServer")
  39. private ThreadPoolExecutor initSipServer() {
  40. int processThreadNum = Runtime.getRuntime().availableProcessors() * 10;
  41. LinkedBlockingQueue<Runnable> processQueue = new LinkedBlockingQueue<Runnable>(10000);
  42. processThreadPool = new ThreadPoolExecutor(processThreadNum,processThreadNum,
  43. 0L,TimeUnit.MILLISECONDS,processQueue,
  44. new ThreadPoolExecutor.CallerRunsPolicy());
  45. return processThreadPool;
  46. }
  47. @Bean("sipFactory")
  48. @DependsOn("initSipServer")
  49. private SipFactory createSipFactory() {
  50. sipFactory = SipFactory.getInstance();
  51. sipFactory.setPathName("gov.nist");
  52. return sipFactory;
  53. }
  54. @Bean("sipStack")
  55. @DependsOn({"initSipServer", "sipFactory"})
  56. private SipStack createSipStack() throws PeerUnavailableException {
  57. Properties properties = new Properties();
  58. properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
  59. properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp());
  60. properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
  61. /**
  62. * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =
  63. * 0; public static final int TRACE_MESSAGES = 16; public static final int
  64. * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32;
  65. */
  66. properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0");
  67. properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
  68. properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");
  69. sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
  70. return sipStack;
  71. }
  72. @Bean("tcpSipProvider")
  73. @DependsOn("sipStack")
  74. private SipProvider startTcpListener() {
  75. ListeningPoint tcpListeningPoint = null;
  76. SipProvider tcpSipProvider = null;
  77. try {
  78. tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "TCP");
  79. tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
  80. tcpSipProvider.addSipListener(this);
  81. logger.info("Sip Server TCP 启动成功 port {" + sipConfig.getSipPort() + "}");
  82. } catch (TransportNotSupportedException | InvalidArgumentException | TooManyListenersException | ObjectInUseException e) {
  83. logger.error(String.format("创建SIP服务失败: %s", e.getMessage()));
  84. }
  85. return tcpSipProvider;
  86. }
  87. @Bean("udpSipProvider")
  88. @DependsOn("sipStack")
  89. private SipProvider startUdpListener() throws Exception {
  90. ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP");
  91. SipProvider udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
  92. udpSipProvider.addSipListener(this);
  93. logger.info("Sip Server UDP 启动成功 port {" + sipConfig.getSipPort() + "}");
  94. return udpSipProvider;
  95. }
  96. /**
  97. * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
  98. * new request arrives.
  99. */
  100. @Override
  101. public void processRequest(RequestEvent evt) {
  102. logger.debug(evt.getRequest().toString());
  103. // 由于jainsip是单线程程序,为提高性能并发处理
  104. processThreadPool.execute(() -> {
  105. if (processorFactory != null) {
  106. processorFactory.createRequestProcessor(evt).process();
  107. }
  108. });
  109. }
  110. @Override
  111. public void processResponse(ResponseEvent evt) {
  112. Response response = evt.getResponse();
  113. logger.debug(evt.getResponse().toString());
  114. int status = response.getStatusCode();
  115. if (((status >= 200) && (status < 300)) || status == 401) { // Success!
  116. ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
  117. try {
  118. processor.process(evt, this, sipConfig);
  119. } catch (ParseException e) {
  120. // TODO Auto-generated catch block
  121. e.printStackTrace();
  122. }
  123. if (evt.getResponse() != null && sipSubscribe.getOkSubscribesSize() > 0 ) {
  124. CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
  125. if (callIdHeader != null) {
  126. SipSubscribe.Event subscribe = sipSubscribe.getOkSubscribe(callIdHeader.getCallId());
  127. if (subscribe != null) {
  128. subscribe.response(evt);
  129. }
  130. }
  131. }
  132. } else if ((status >= 100) && (status < 200)) {
  133. // 增加其它无需回复的响应,如101、180等
  134. } else {
  135. logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
  136. if (evt.getResponse() != null && sipSubscribe.getErrorSubscribesSize() > 0 ) {
  137. CallIdHeader callIdHeader = (CallIdHeader)evt.getResponse().getHeader(CallIdHeader.NAME);
  138. if (callIdHeader != null) {
  139. SipSubscribe.Event subscribe = sipSubscribe.getErrorSubscribe(callIdHeader.getCallId());
  140. if (subscribe != null) {
  141. subscribe.response(evt);
  142. }
  143. }
  144. }
  145. }
  146. }
  147. /**
  148. * <p>
  149. * Title: processTimeout
  150. * </p>
  151. * <p>
  152. * Description:
  153. * </p>
  154. *
  155. * @param timeoutEvent
  156. */
  157. @Override
  158. public void processTimeout(TimeoutEvent timeoutEvent) {
  159. // TODO Auto-generated method stub
  160. }
  161. /**
  162. * <p>
  163. * Title: processIOException
  164. * </p>
  165. * <p>
  166. * Description:
  167. * </p>
  168. *
  169. * @param exceptionEvent
  170. */
  171. @Override
  172. public void processIOException(IOExceptionEvent exceptionEvent) {
  173. // TODO Auto-generated method stub
  174. }
  175. /**
  176. * <p>
  177. * Title: processTransactionTerminated
  178. * </p>
  179. * <p>
  180. * Description:
  181. * </p>
  182. *
  183. * @param transactionTerminatedEvent
  184. */
  185. @Override
  186. public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
  187. // TODO Auto-generated method stub
  188. }
  189. /**
  190. * <p>
  191. * Title: processDialogTerminated
  192. * </p>
  193. * <p>
  194. * Description:
  195. * </p>
  196. *
  197. * @param dialogTerminatedEvent
  198. */
  199. @Override
  200. public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
  201. // TODO Auto-generated method stub
  202. }
  203. }