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 | 7 | import javax.sip.InvalidArgumentException; |
| 8 | 8 | import javax.sip.ResponseEvent; |
| 9 | 9 | import javax.sip.SipException; |
| 10 | +import javax.sip.address.Address; | |
| 10 | 11 | import javax.sip.address.SipURI; |
| 11 | 12 | import javax.sip.header.CSeqHeader; |
| 13 | +import javax.sip.header.ContactHeader; | |
| 14 | +import javax.sip.header.FromHeader; | |
| 12 | 15 | import javax.sip.header.ViaHeader; |
| 13 | 16 | import javax.sip.message.Request; |
| 14 | 17 | import javax.sip.message.Response; |
| ... | ... | @@ -22,57 +25,78 @@ import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 22 | 25 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; |
| 23 | 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 | 32 | * @Description:处理INVITE响应 |
| 27 | 33 | * @author: songww |
| 28 | - * @date: 2020年5月3日 下午4:43:52 | |
| 34 | + * @date: 2020年5月3日 下午4:43:52 | |
| 29 | 35 | */ |
| 30 | 36 | @Component |
| 31 | 37 | public class InviteResponseProcessor implements ISIPResponseProcessor { |
| 32 | 38 | |
| 33 | 39 | private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class); |
| 34 | - | |
| 40 | + | |
| 35 | 41 | /** |
| 36 | 42 | * 处理invite响应 |
| 37 | 43 | * |
| 38 | - * @param evt | |
| 39 | - * 响应消息 | |
| 40 | - */ | |
| 44 | + * @param evt 响应消息 | |
| 45 | + * @throws ParseException | |
| 46 | + */ | |
| 41 | 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 | 49 | try { |
| 44 | 50 | Response response = evt.getResponse(); |
| 45 | 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 | 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 | 100 | dialog.sendAck(reqAck); |
| 77 | 101 | } |
| 78 | 102 | } catch (InvalidArgumentException | SipException e) { | ... | ... |