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.dialog = timeoutEvent.getClientTransaction().getDialog(); 
 | 
                this.callId = this.dialog != null?timeoutEvent.getClientTransaction().getDialog().getCallId().getCallId(): null; 
 | 
            }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.dialog = deviceNotFoundEvent.getDialog(); 
 | 
                this.callId = this.dialog != null ?deviceNotFoundEvent.getDialog().getCallId().getCallId() : null; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    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) { 
 | 
        if(key == null){ 
 | 
            return; 
 | 
        } 
 | 
        errorSubscribes.remove(key); 
 | 
        errorTimeSubscribes.remove(key); 
 | 
    } 
 | 
  
 | 
    public SipSubscribe.Event getOkSubscribe(String key) { 
 | 
        return okSubscribes.get(key); 
 | 
    } 
 | 
  
 | 
    public void removeOkSubscribe(String key) { 
 | 
        if(key == null){ 
 | 
            return; 
 | 
        } 
 | 
        okSubscribes.remove(key); 
 | 
        okTimeSubscribes.remove(key); 
 | 
    } 
 | 
    public int getErrorSubscribesSize(){ 
 | 
        return errorSubscribes.size(); 
 | 
    } 
 | 
    public int getOkSubscribesSize(){ 
 | 
        return okSubscribes.size(); 
 | 
    } 
 | 
} 
 |