| package com.genersoft.iot.vmp.gb28181.event; | 
|   | 
| import com.genersoft.iot.vmp.gb28181.bean.DeviceNotFoundEvent; | 
| import org.slf4j.Logger; | 
| import org.slf4j.LoggerFactory; | 
| import org.springframework.scheduling.annotation.Scheduled; | 
| import org.springframework.stereotype.Component; | 
|   | 
| import javax.sip.*; | 
| import javax.sip.header.CallIdHeader; | 
| import javax.sip.message.Response; | 
| import java.time.Instant; | 
| import java.util.Map; | 
| import java.util.concurrent.ConcurrentHashMap; | 
| import java.util.concurrent.TimeUnit; | 
|   | 
| /** | 
|  * @author lin | 
|  */ | 
| @Component | 
| public class SipSubscribe { | 
|   | 
|     private final Logger logger = LoggerFactory.getLogger(SipSubscribe.class); | 
|   | 
|     private Map<String, SipSubscribe.Event> errorSubscribes = new ConcurrentHashMap<>(); | 
|   | 
|     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 * * * * ?")   //每五秒执行一次 | 
|     //    @Scheduled(fixedRate= 100 * 60 * 60 ) | 
|     @Scheduled(cron="0 0/5 * * * ?")   //每5分钟执行一次 | 
|     public void execute(){ | 
|         logger.info("[定时任务] 清理过期的SIP订阅信息"); | 
|   | 
|         Instant instant = Instant.now().minusMillis(TimeUnit.MINUTES.toMillis(5)); | 
|   | 
|         for (String key : okTimeSubscribes.keySet()) { | 
|             if (okTimeSubscribes.get(key).isBefore(instant)){ | 
|                 okSubscribes.remove(key); | 
|                 okTimeSubscribes.remove(key); | 
|             } | 
|         } | 
|         for (String key : errorTimeSubscribes.keySet()) { | 
|             if (errorTimeSubscribes.get(key).isBefore(instant)){ | 
|                 errorSubscribes.remove(key); | 
|                 errorTimeSubscribes.remove(key); | 
|             } | 
|         } | 
|         logger.debug("okTimeSubscribes.size:{}",okTimeSubscribes.size()); | 
|         logger.debug("okSubscribes.size:{}",okSubscribes.size()); | 
|         logger.debug("errorTimeSubscribes.size:{}",errorTimeSubscribes.size()); | 
|         logger.debug("errorSubscribes.size:{}",errorSubscribes.size()); | 
|     } | 
|   | 
|     public interface Event { | 
|         void response(EventResult eventResult); | 
|     } | 
|   | 
|     public static class EventResult<EventObject>{ | 
|         public int statusCode; | 
|         public String type; | 
|         public String msg; | 
|         public String callId; | 
|         public Dialog dialog; | 
|         public EventObject event; | 
|   | 
|         public EventResult() { | 
|         } | 
|   | 
|         public EventResult(EventObject event) { | 
|             this.event = event; | 
|             if (event instanceof ResponseEvent) { | 
|                 ResponseEvent responseEvent = (ResponseEvent)event; | 
|                 Response response = responseEvent.getResponse(); | 
|                 this.dialog = responseEvent.getDialog(); | 
|                 this.type = "response"; | 
|                 if (response != null) { | 
|                     this.msg = response.getReasonPhrase(); | 
|                     this.statusCode = response.getStatusCode(); | 
|                 } | 
|                 this.callId = ((CallIdHeader)response.getHeader(CallIdHeader.NAME)).getCallId(); | 
|   | 
|             }else if (event instanceof TimeoutEvent) { | 
|                 TimeoutEvent timeoutEvent = (TimeoutEvent)event; | 
|                 this.type = "timeout"; | 
|                 this.msg = "消息超时未回复"; | 
|                 this.statusCode = -1024; | 
|                 this.callId = timeoutEvent.getClientTransaction().getDialog().getCallId().getCallId(); | 
|                 this.dialog = timeoutEvent.getClientTransaction().getDialog(); | 
|             }else if (event instanceof TransactionTerminatedEvent) { | 
|                 TransactionTerminatedEvent transactionTerminatedEvent = (TransactionTerminatedEvent)event; | 
|                 this.type = "transactionTerminated"; | 
|                 this.msg = "事务已结束"; | 
|                 this.statusCode = -1024; | 
|                 this.callId = transactionTerminatedEvent.getClientTransaction().getDialog().getCallId().getCallId(); | 
|                 this.dialog = transactionTerminatedEvent.getClientTransaction().getDialog(); | 
|             }else if (event instanceof DialogTerminatedEvent) { | 
|                 DialogTerminatedEvent dialogTerminatedEvent = (DialogTerminatedEvent)event; | 
|                 this.type = "dialogTerminated"; | 
|                 this.msg = "会话已结束"; | 
|                 this.statusCode = -1024; | 
|                 this.callId = dialogTerminatedEvent.getDialog().getCallId().getCallId(); | 
|                 this.dialog = dialogTerminatedEvent.getDialog(); | 
|             }else if (event instanceof DeviceNotFoundEvent) { | 
|                 DeviceNotFoundEvent deviceNotFoundEvent = (DeviceNotFoundEvent)event; | 
|                 this.type = "deviceNotFoundEvent"; | 
|                 this.msg = "设备未找到"; | 
|                 this.statusCode = -1024; | 
|                 this.callId = deviceNotFoundEvent.getDialog().getCallId().getCallId(); | 
|                 this.dialog = deviceNotFoundEvent.getDialog(); | 
|             } | 
|         } | 
|     } | 
|   | 
|     public void addErrorSubscribe(String key, SipSubscribe.Event event) { | 
|         errorSubscribes.put(key, event); | 
|         errorTimeSubscribes.put(key, Instant.now()); | 
|     } | 
|   | 
|     public void addOkSubscribe(String key, SipSubscribe.Event event) { | 
|         okSubscribes.put(key, event); | 
|         okTimeSubscribes.put(key, Instant.now()); | 
|     } | 
|   | 
|     public SipSubscribe.Event getErrorSubscribe(String key) { | 
|         return errorSubscribes.get(key); | 
|     } | 
|   | 
|     public void removeErrorSubscribe(String key) { | 
|         errorSubscribes.remove(key); | 
|         errorTimeSubscribes.remove(key); | 
|     } | 
|   | 
|     public SipSubscribe.Event getOkSubscribe(String key) { | 
|         return okSubscribes.get(key); | 
|     } | 
|   | 
|     public void removeOkSubscribe(String key) { | 
|         okSubscribes.remove(key); | 
|         okTimeSubscribes.remove(key); | 
|     } | 
|     public int getErrorSubscribesSize(){ | 
|         return errorSubscribes.size(); | 
|     } | 
|     public int getOkSubscribesSize(){ | 
|         return okSubscribes.size(); | 
|     } | 
| } |