[本文转自:http://www.oracle.com/technology/pub/articles/dev2arch/2007/10/introduction-jain-sip.html]
Sending a SIP Request
Let's now write a method to send a SIP message with the JAIN SIP API.
In the prerequisites I suggested that you must know SIP fairly well before you can start using the SIP API. You'll now see what I mean by that! The SIP API is quite a low-level abstraction and, in most cases, doesn't use default values or hide headers, request URIs, or contents of SIP messages. The advantage of this design is that you have complete control over what SIP messages contain.
The following method is a bit lengthy. It prepares and sends a SIP request. It can roughly be split into four subsections:
- Create main elements
- Create message
- Complete message
- Send message
The following main SIP elements are minimally needed to construct a message using the JAIN SIP API:
- Request URI
- Method
- Call-ID header
- CSeq header
- From header
- An array of Via headers
- Max-forwards header
For information about these elements, please see An Introduction to SIP, Part 1 (Dev2Dev, 2006). The following code snippet creates all of these elements:
public void sendMessage(String to, String message) throws
ParseException, InvalidArgumentException, SipException {
SipURI from = addressFactory.createSipURI(getUsername(),
getHost() + ":" + getPort());
Address fromNameAddress = addressFactory.createAddress(from);
fromNameAddress.setDisplayName(getUsername());
FromHeader fromHeader =
headerFactory.createFromHeader(fromNameAddress,
"textclientv1.0");
String username = to.substring(to.indexOf(":")+1, to.indexOf("@"));
String address = to.substring(to.indexOf("@")+1);
SipURI toAddress =
addressFactory.createSipURI(username, address);
Address toNameAddress = addressFactory.createAddress(toAddress);
toNameAddress.setDisplayName(username);
ToHeader toHeader =
headerFactory.createToHeader(toNameAddress, null);
SipURI requestURI =
addressFactory.createSipURI(username, address);
requestURI.setTransportParam("udp");
ArrayList viaHeaders = new ArrayList();
ViaHeader viaHeader =
headerFactory.createViaHeader(
getHost(),
getPort(),
"udp",
null);
viaHeaders.add(viaHeader);
CallIdHeader callIdHeader = sipProvider.getNewCallId();
CSeqHeader cSeqHeader =
headerFactory.createCSeqHeader(1, Request.MESSAGE);
MaxForwardsHeader maxForwards =
headerFactory.createMaxForwardsHeader(70);
...
I'm using factories that were created in the constructor,
HeaderFactory and AddressFactory, to instantiate these elements.
Next let's instantiate the actual SIP message itself, passing in all the elements created earlier:
Request request = messageFactory.createRequest(
requestURI, Request.MESSAGE, callIdHeader, cSeqHeader,
fromHeader, toHeader, viaHeaders, maxForwards);
...
Note the use of MessageFactory for this step.
Then let's add other elements to the message: a contact header and the contents of the message (payload). It's possible to add custom headers too at this point.
SipURI contactURI = addressFactory.createSipURI(getUsername(),
getHost());
contactURI.setPort(getPort());
Address contactAddress = addressFactory.createAddress(contactURI);
contactAddress.setDisplayName(getUsername());
ContactHeader contactHeader =
headerFactory.createContactHeader(contactAddress);
request.addHeader(contactHeader);
ContentTypeHeader contentTypeHeader =
headerFactory.createContentTypeHeader("text", "plain");
request.setContent(message, contentTypeHeader);
...
For more information on how to further massage the request, there's a description of the
Request interface in appendix.
Lastly, you send the message using the
SipProvider instance:
sipProvider.sendRequest(request);
}
Sending Messages Inside a Dialog
You're sending our message outside a dialog. That means messages are not related to each other. This works well for a simple instant-messaging application like the TextClient.
An alternative would be to create a dialog (sometimes called a session) using an INVITE message, and then send messages inside this dialog. The TextClient doesn't use this technique. However, I think it's something worth learning. So as a compromise, this subsection describes how it's done.
Sending a message inside a dialog requires the creation of
Dialog and Transaction objects. On the initial message (that is, the message that creates the dialog), instead of using the provider to send out the message, you instantiate a
Transaction and then get the Dialog from it. You keep the
Dialog reference for later. You then use the Transaction to send the message:
ClientTransaction trans = sipProvider.getNewClientTransaction(invite);
dialog = trans.getDialog();
trans.sendRequest();
Later when you wish to send a new message inside the same dialog, you use the
Dialog object from before to create a new request. You can then massage the request and, lastly, use the
Transaction to send out the message.
request = dialog.createRequest(Request.MESSAGE);
request.setHeader(contactHeader);
request.setContent(message, contentTypeHeader);
ClientTransaction trans = sipProvider.getNewClientTransaction(request);
trans.sendRequest();
Essentially, you're skipping the "create main elements" step when sending a message inside an existing dialog. When you use an INVITE to create a dialog, don't forget to clean it up by sending an in-dialog BYE message at the end. This technique is also used to refresh registrations and subscriptions.
Previously, you've seen the
SipListener interface, which contains the processDialogTerminated() and
processTransactionTerminated() methods. These are called automatically at the end of a dialog and transaction, respectively. Typically, you implement these methods to clean things up (for example, discard the
Dialog and Transaction instances). You'll leave these two methods empty as you don't need them in TextClient.
本文介绍如何利用JAIN SIP API构建并发送SIP请求消息,包括创建主要元素、构造消息、完善消息及发送消息等步骤,并探讨了在对话内外发送消息的不同方式。
457

被折叠的 条评论
为什么被折叠?



