package com.ard.gb28181.transmit.event.request.impl.message; import com.ard.gb28181.api.bean.DeviceNotFoundEvent; import com.ard.gb28181.api.domain.Device; import com.ard.gb28181.api.domain.SsrcTransaction; import com.ard.gb28181.service.IRedisCatchStorage; import com.ard.gb28181.session.SipInviteSessionManager; import com.ard.gb28181.transmit.ISIPProcessorObserver; import com.ard.gb28181.transmit.event.SipSubscribe; import com.ard.gb28181.transmit.event.request.ISIPRequestProcessor; import com.ard.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.ard.gb28181.transmit.event.sip.SipEvent; import com.ard.gb28181.api.utils.SipUtils; import gov.nist.javax.sip.message.SIPRequest; import lombok.extern.slf4j.Slf4j; import org.dom4j.DocumentException; import org.dom4j.Element; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; import javax.sip.SipException; import javax.sip.header.CSeqHeader; import javax.sip.header.CallIdHeader; import javax.sip.message.Response; import java.text.ParseException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Slf4j @Component public class MessageRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor { private final String method = "MESSAGE"; private static final Map messageHandlerMap = new ConcurrentHashMap<>(); @Autowired private ISIPProcessorObserver sipProcessorObserver; @Autowired private SipSubscribe sipSubscribe; @Autowired private IRedisCatchStorage redisCatchStorage; @Autowired private SipInviteSessionManager sessionManager; @Override public void afterPropertiesSet() throws Exception { // 添加消息处理的订阅 sipProcessorObserver.addRequestProcessor(method, this); } public void addHandler(String name, IMessageHandler handler) { messageHandlerMap.put(name, handler); } @Override public void process(RequestEvent evt) { SIPRequest sipRequest = (SIPRequest) evt.getRequest(); // logger.info("接收到消息:" + evt.getRequest()); String deviceId = SipUtils.getUserIdFromFromHeader(evt.getRequest()); CallIdHeader callIdHeader = sipRequest.getCallIdHeader(); CSeqHeader cSeqHeader = sipRequest.getCSeqHeader(); // 先从会话内查找 SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByCallId(callIdHeader.getCallId()); // 兼容海康 媒体通知 消息from字段不是设备ID的问题 if (ssrcTransaction != null) { deviceId = ssrcTransaction.getDeviceId(); } SIPRequest request = (SIPRequest) evt.getRequest(); // 查询设备是否存在 Device device = redisCatchStorage.getDevice(deviceId); try { if (device != null) { String hostAddress = request.getRemoteAddress().getHostAddress(); int remotePort = request.getRemotePort(); if (device.getHostAddress().equals(hostAddress + ":" + remotePort)) { } else { device = null; } } if (device == null) { // 不存在则回复404 responseAck(request, Response.NOT_FOUND, "device " + deviceId + " not found"); log.warn("[设备未找到 ]deviceId: {}, callId: {}", deviceId, callIdHeader.getCallId()); SipEvent sipEvent = sipSubscribe.getSubscribe(callIdHeader.getCallId() + cSeqHeader.getSeqNumber()); if (sipEvent != null && sipEvent.getErrorEvent() != null) { DeviceNotFoundEvent deviceNotFoundEvent = new DeviceNotFoundEvent(callIdHeader.getCallId()); SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(deviceNotFoundEvent); sipEvent.getErrorEvent().response(eventResult); } } else { Element rootElement; try { rootElement = getRootElement(evt); if (rootElement == null) { log.error("处理MESSAGE请求 未获取到消息体{}", evt.getRequest()); responseAck(request, Response.BAD_REQUEST, "content is null"); return; } String name = rootElement.getName(); IMessageHandler messageHandler = messageHandlerMap.get(name); if (messageHandler != null) { if (device != null) { messageHandler.handForDevice(evt, device, rootElement); } } else { // 不支持的message // 不存在则回复415 responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE, "Unsupported message type, must Control/Notify/Query/Response"); } } catch (DocumentException e) { log.warn("解析XML消息内容异常", e); // 不存在则回复404 responseAck(request, Response.BAD_REQUEST, e.getMessage()); } } } catch (SipException e) { log.warn("SIP 回复错误", e); } catch (InvalidArgumentException e) { log.warn("参数无效", e); } catch (ParseException e) { log.warn("SIP回复时解析异常", e); } } }