Commit 4ca7307eea4364567f5fa51b099dbb98b4c49e9f
1 parent
85e6beaf
修正invite后收到部分设备200 OK无法回复ack的问题
Showing
1 changed file
with
59 additions
and
35 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
| @@ -7,8 +7,11 @@ import javax.sip.Dialog; | @@ -7,8 +7,11 @@ import javax.sip.Dialog; | ||
| 7 | import javax.sip.InvalidArgumentException; | 7 | import javax.sip.InvalidArgumentException; |
| 8 | import javax.sip.ResponseEvent; | 8 | import javax.sip.ResponseEvent; |
| 9 | import javax.sip.SipException; | 9 | import javax.sip.SipException; |
| 10 | +import javax.sip.address.Address; | ||
| 10 | import javax.sip.address.SipURI; | 11 | import javax.sip.address.SipURI; |
| 11 | import javax.sip.header.CSeqHeader; | 12 | import javax.sip.header.CSeqHeader; |
| 13 | +import javax.sip.header.ContactHeader; | ||
| 14 | +import javax.sip.header.FromHeader; | ||
| 12 | import javax.sip.header.ViaHeader; | 15 | import javax.sip.header.ViaHeader; |
| 13 | import javax.sip.message.Request; | 16 | import javax.sip.message.Request; |
| 14 | import javax.sip.message.Response; | 17 | import javax.sip.message.Response; |
| @@ -22,57 +25,78 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; | @@ -22,57 +25,78 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; | ||
| 22 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; | 25 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; |
| 23 | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; | 26 | import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; |
| 24 | 27 | ||
| 25 | -/** | 28 | +// import java.util.regex.Pattern; |
| 29 | +// import java.util.regex.Matcher; | ||
| 30 | + | ||
| 31 | +/** | ||
| 26 | * @Description:处理INVITE响应 | 32 | * @Description:处理INVITE响应 |
| 27 | * @author: songww | 33 | * @author: songww |
| 28 | - * @date: 2020年5月3日 下午4:43:52 | 34 | + * @date: 2020年5月3日 下午4:43:52 |
| 29 | */ | 35 | */ |
| 30 | @Component | 36 | @Component |
| 31 | public class InviteResponseProcessor implements ISIPResponseProcessor { | 37 | public class InviteResponseProcessor implements ISIPResponseProcessor { |
| 32 | 38 | ||
| 33 | private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class); | 39 | private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class); |
| 34 | - | 40 | + |
| 35 | /** | 41 | /** |
| 36 | * 处理invite响应 | 42 | * 处理invite响应 |
| 37 | * | 43 | * |
| 38 | - * @param evt | ||
| 39 | - * 响应消息 | ||
| 40 | - */ | 44 | + * @param evt 响应消息 |
| 45 | + * @throws ParseException | ||
| 46 | + */ | ||
| 41 | @Override | 47 | @Override |
| 42 | - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) { | 48 | + public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException { |
| 43 | try { | 49 | try { |
| 44 | Response response = evt.getResponse(); | 50 | Response response = evt.getResponse(); |
| 45 | int statusCode = response.getStatusCode(); | 51 | int statusCode = response.getStatusCode(); |
| 46 | - //trying不会回复 | ||
| 47 | - if(statusCode == Response.TRYING){ | ||
| 48 | - | 52 | + // trying不会回复 |
| 53 | + if (statusCode == Response.TRYING) { | ||
| 49 | } | 54 | } |
| 50 | - //成功响应 | ||
| 51 | - //下发ack | ||
| 52 | - if(statusCode == Response.OK){ | ||
| 53 | -// ClientTransaction clientTransaction = evt.getClientTransaction(); | ||
| 54 | -// if(clientTransaction == null){ | ||
| 55 | -// logger.error("回复ACK时,clientTransaction为null >>> {}",response); | ||
| 56 | -// return; | ||
| 57 | -// } | ||
| 58 | -// Dialog clientDialog = clientTransaction.getDialog(); | ||
| 59 | -// | ||
| 60 | -// CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); | ||
| 61 | -// long cseqId = clientCSeqHeader.getSeqNumber(); | ||
| 62 | -// /* | ||
| 63 | -// createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 | ||
| 64 | -// 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 | ||
| 65 | -// 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 | ||
| 66 | -// */ | ||
| 67 | -// Request ackRequest = clientDialog.createAck(cseqId); | ||
| 68 | -// SipURI requestURI = (SipURI) ackRequest.getRequestURI(); | ||
| 69 | -// ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); | ||
| 70 | -// requestURI.setHost(viaHeader.getHost()); | ||
| 71 | -// requestURI.setPort(viaHeader.getPort()); | ||
| 72 | -// clientDialog.sendAck(ackRequest); | ||
| 73 | - | 55 | + // 成功响应 |
| 56 | + // 下发ack | ||
| 57 | + if (statusCode == Response.OK) { | ||
| 58 | + // ClientTransaction clientTransaction = evt.getClientTransaction(); | ||
| 59 | + // if(clientTransaction == null){ | ||
| 60 | + // logger.error("回复ACK时,clientTransaction为null >>> {}",response); | ||
| 61 | + // return; | ||
| 62 | + // } | ||
| 63 | + // Dialog clientDialog = clientTransaction.getDialog(); | ||
| 64 | + | ||
| 65 | + // CSeqHeader clientCSeqHeader = (CSeqHeader) | ||
| 66 | + // response.getHeader(CSeqHeader.NAME); | ||
| 67 | + // long cseqId = clientCSeqHeader.getSeqNumber(); | ||
| 68 | + // /* | ||
| 69 | + // createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 | ||
| 70 | + // 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 | ||
| 71 | + // 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 | ||
| 72 | + // */ | ||
| 73 | + // Request ackRequest = clientDialog.createAck(cseqId); | ||
| 74 | + // SipURI requestURI = (SipURI) ackRequest.getRequestURI(); | ||
| 75 | + // ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); | ||
| 76 | + // try { | ||
| 77 | + // requestURI.setHost(viaHeader.getHost()); | ||
| 78 | + // } catch (Exception e) { | ||
| 79 | + // e.printStackTrace(); | ||
| 80 | + // } | ||
| 81 | + // requestURI.setPort(viaHeader.getPort()); | ||
| 82 | + // clientDialog.sendAck(ackRequest); | ||
| 83 | + | ||
| 74 | Dialog dialog = evt.getDialog(); | 84 | Dialog dialog = evt.getDialog(); |
| 75 | - Request reqAck =dialog.createAck(1L); | 85 | + CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); |
| 86 | + Request reqAck = dialog.createAck(cseq.getSeqNumber()); | ||
| 87 | + | ||
| 88 | + SipURI requestURI = (SipURI) reqAck.getRequestURI(); | ||
| 89 | + ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); | ||
| 90 | + // String viaHost =viaHeader.getHost(); | ||
| 91 | + //getHost()函数取回的IP地址是“[xxx.xxx.xxx.xxx:yyyy]”的格式,需用正则表达式截取为“xxx.xxx.xxx.xxx"格式 | ||
| 92 | + // Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+"); | ||
| 93 | + // Matcher matcher = p.matcher(viaHeader.getHost()); | ||
| 94 | + // if (matcher.find()) { | ||
| 95 | + // requestURI.setHost(matcher.group()); | ||
| 96 | + // } | ||
| 97 | + requestURI.setHost(viaHeader.getHost()); | ||
| 98 | + requestURI.setPort(viaHeader.getPort()); | ||
| 99 | + reqAck.setRequestURI(requestURI); | ||
| 76 | dialog.sendAck(reqAck); | 100 | dialog.sendAck(reqAck); |
| 77 | } | 101 | } |
| 78 | } catch (InvalidArgumentException | SipException e) { | 102 | } catch (InvalidArgumentException | SipException e) { |