使用java编写sip通信协议。
一个客户端(部署在内网),一个服务端部署在阿里云平台。
客户端能向上级发送消息进行通信,但是云上服务不能通过sip主动调用内网服务。(好像涉及了通道概念)
要使上级主动调用下级,可以使用SIP INVITE请求。该请求通常由一个用户代理(例如软电话或SIP电话)发送,请求建立会话。当服务端收到INVITE请求时,会向客户端发送响应,表示是否接受请求。如果响应为200 OK,则会话已建立。
使用Java编写SIP通信协议的代码大概是这样:
import javax.sip.*;
import javax.sip.address.*;
import javax.sip.header.*;
import javax.sip.message.*;
public class SipClient {
private SipFactory sipFactory;
private SipStack sipStack;
private SipProvider sipProvider;
private HeaderFactory headerFactory;
private AddressFactory addressFactory;
private MessageFactory messageFactory;
private String toUri;
private String fromUri;
private String transport;
public SipClient(String toUri, String fromUri, String transport) throws Exception {
this.toUri = toUri;
this.fromUri = fromUri;
this.transport = transport;
this.init();
}
private void init() throws Exception {
this.sipFactory = SipFactory.getInstance();
this.sipFactory.setPathName("gov.nist");
this.sipStack = this.sipFactory.createSipStack(null);
this.headerFactory = this.sipFactory.createHeaderFactory();
this.addressFactory = this.sipFactory.createAddressFactory();
this.messageFactory = this.sipFactory.createMessageFactory();
ListeningPoint listeningPoint = this.sipStack.createListeningPoint("127.0.0.1", 5060, this.transport);
this.sipProvider = this.sipStack.createSipProvider(listeningPoint);
}
public void sendInvite(String message) throws Exception {
Address toAddress = this.addressFactory.createAddress(this.toUri);
Address fromAddress = this.addressFactory.createAddress(this.fromUri);
CallIdHeader callIdHeader = this.sipProvider.getNewCallId();
CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(1, Request.INVITE);
MaxForwardsHeader maxForwardsHeader = this.headerFactory.createMaxForwardsHeader(70);
Request request = this.messageFactory.createRequest(toAddress.getURI(), Request.INVITE, callIdHeader, cSeqHeader, fromAddress, toAddress, maxForwardsHeader);
request.setContent(message, this.headerFactory.createContentTypeHeader("text", "plain"));
this.sipProvider.sendRequest(request);
}
}
在客户端中,可以创建一个SipClient对象,并调用sendInvite方法发送INVITE请求。例如:
SipClient client = new SipClient("sip:service@example.com", "sip:user@example.com", "udp");
client.sendInvite("Hello, world!");
要让云上的服务主动调用内网服务,您需要使用NAT(网络地址转换)穿透技术。由于内网服务的IP地址是私有的,外部网络无法直接访问它。您需要在内网中部署一个SIP代理服务器,该代理服务器可将内网服务的SIP信令转发到公网,公网服务就可以通过代理服务器与内网服务进行通信。您可以使用OpenSIPS或Asterisk等SIP代理服务器软件来实现这一点。
简单来说就是,需要在内网中部署一个SIP代理服务器,并配置该代理服务器的NAT穿透规则,以便外部网络可以通过代理服务器访问内网服务。还需要将客户端和服务端的SIP地址与代理服务器进行注册,以便代理服务器能够将信令正确路由到目标设备。这些操作通常需要对SIP代理服务器的配置文件进行修改,具体操作可以参考相应的软件文档。一旦代理服务器配置完成就可以在公网服务中发送SIP INVITE请求,请求与内网服务建立会话。代理服务器将接收到的INVITE请求转发到内网服务,内网服务可以向公网服务发送响应,建立会话。在此过程中,代理服务器将起到信令转发的作用,使公网服务能够与内网服务进行通信。