[转]Introduction to JAIN SIP API part3_FINAL
来源:互联网 发布:怎么更改mac管理员名称 编辑:程序博客网 时间:2024/05/17 01:10
[本文转自http://www.oracle.com/technology/pub/articles/dev2arch/2007/10/introduction-jain-sip3.html]
Receiving a Response
Earlier, you registered a listener of incoming messages. The listener interface,SipListener
, contains the method processResponse()
, which is called by the SIP stack when a SIP response message arrives.processResponse()
takes a single parameter of type ResponseEvent
, which encapsulates aResponse
object. Let's implement this method now.
public void processResponse(ResponseEvent evt) {Response response = evt.getResponse();int status = response.getStatusCode();if( (status >= 200) && (status < 300) ) { //Success!messageProcessor.processInfo("--Sent");return;}messageProcessor.processError("Previous message not sent: " +status);}
In this method you check if the response of an earlier MESSAGE message represents a success (2xx range of status codes) or an error (otherwise). You then relay this information back to the user through the callback interface.
Typically, you read only the Response
object in theprocessResponse()
method. The only exception is for a success response to an INVITE message; in this case, you must send an ACK request right back, like this:
Dialog dialog = evt.getClientTransaction().getDialog()Request ack = dialog.createAck()dialog.sendAck( ack );
For a description of the Response
interface, refer to theAppendix.
Receiving a Request
Receiving a SIP request message is just as easy as receiving a response. You just implement another method of theSipListener
interface, processRequest()
, and the SIP stack will call it automatically. The single parameter of this method is aRequestEvent
object, which contains (you guessed it) a Request
object. This is the same type that you've seen before, and it has the same methods. However, you shouldn't set any fields on an incoming request as it doesn't make much sense.
A typical implementation of processRequest()
analyzes the request, and then creates and sends back an appropriate response. This is what you'll do now:
public void processRequest(RequestEvent evt) {Request req = evt.getRequest();String method = req.getMethod();if( ! method.equals("MESSAGE")) { //bad request type.messageProcessor.processError("Bad request type: " + method);return;}FromHeader from = (FromHeader)req.getHeader("From");messageProcessor.processMessage(from.getAddress().toString(),new String(req.getRawContent()));Response response=null;try { //Reply with OKresponse = messageFactory.createResponse(200, req);ToHeader toHeader = (ToHeader)response.getHeader(ToHeader.NAME);toHeader.setTag("888"); //Identifier, specific to your applicationServerTransaction st = sipProvider.getNewServerTransaction(req);st.sendResponse(response);} catch (Throwable e) {e.printStackTrace();messageProcessor.processError("Can't send OK reply.");}}
In this case, you always reply with a success response (200), but you could also send back any of the error responses (typically 4xx range). Here's a useful list ofSIP status codes.
Dealing With Error Conditions
There are other methods in the SipListener
interface that you haven't implemented yet. They are called by the SIP stack when a request cannot be sent for specific reasons. For example, theprocessTimeout()
is called when the end point receiving the message doesn't answer in time. This is a special situation for which there is no response, so noResponse
object is available. The TimeoutEvent
parameter contains, among other things, theClientTransaction
of the request that timed out, and you can use this to link back to the original request if you want to. In this implementation you simply inform the user using the callback interface:
public void processTimeout(TimeoutEvent evt) {messageProcessor.processError("Previous message not sent: " +"timeout");}
Similarily, Input/Output (IO) errors are processed using the following method:
public void processIOException(IOExceptionEvent evt) {messageProcessor.processError("Previous message not sent: " +"I/O Exception");}
Point-to-Point vs. Client/Server
SIP client applications can be used standalone (point to point) or together with a server to provide extra functionality like proxying or call routing.
I suggest you have a look at my Aarticle on SIP Servlets. It contains a neat SIP Server application that can work with TextClient to provide a chat room-type service. This illustrates how you can use the TextClient together with the BEA WebLogic SIP Server and double its usefulness.
Download
Download the TextClient source code here.
Summary
This article provides an overview of the JAIN SIP API, and I've shown how to write a simple application to use this technology. Right now, you should have a pretty good idea of the APIs available, and know how to write your own IM client with SIP.
Nevertheless, why stop here? I could add many more features to this application. And as I said before, if the client talks with a server application, you can double its usefulness. If you need suggestions, consider the following:
- Automatic text answers, store-and-forward (for example, "John is offline right now, but he will receive your messages as soon as he logs back in")
- A neat networked checkers video game
- A location-based service for your laptop
- A media-sharing client
- An RSS-like client
The possibilities are almost limitless.
References
- A concise tutorial, including SIP message formats. Be sure to read the section "Relation among Call, Dialog, Transaction & Message" (external tutorial)
- Standard SIP stack properties
- Non-standard SIP stack properties of the reference implementation
- SIP status codes
- RTP stack
- SIP Communicator (java.net project)
Appendix
This section is a reference to the various classes and interfaces available in the JAIN SIP API.
API overview
Here's an overview of the main classes and interfaces found in the JAIN SIP API reference implementation.
Class / InterfaceDescriptionSipFactory / AddressFactory / HeaderFactory / MessageFactory
Factory classes to create the various objects of the system. They return objects that implement standard interfaces.SipStack
The first interface you'll need, used to create ListeningPoint
s andSipProvider
s.ListeningPoint
This interface encapsulates a transport/port pair (for example, UDP/5060).SipProvider
This interface is used to send SIP messages. You can also register a listener for incoming SIP messages using this interface. SeeSipListener
below.SipListener
You must implement this interface to allow receiving incoming SIP messages.RequestEvent / ResponseEvent
Represent an incoming SIP request, response. Passed to your SipListener
for processing. Contains aRequest
or Response
object, respectively.TimeoutEvent
Represents a failure condition when there's no reply to an outgoing request. Passed to yourSipListener
for processing.IOExceptionEvent
Represents a failure condition when there's an Input/Output problem sending an outgoing request. Passed to yourSipListener
for processing.Request / Response
Represent a SIP request, response. Both are sub-interfaces of the Message
interface. They provide access to headers, content, and other parts of SIP messages.Dialog
An object of this interface encapsulates a SIP dialog. (Reminder: In a dialog all messages are related to the same call; a dialog often starts with an INVITE and ends with a BYE.)ClientTransaction / ServerTransaction
Encapsulate SIP transactions. (Reminder: A transaction starts with a request and ends with a final response. Transactions often live within a dialog.)Message
Interface
The Message
interface is the base interface for SIP messages. For your reference, here's an overview of available methods.
void addHeader(Header)
void setHeader(Header)
Sets header fields to the SIP message. The first method can be used for headers that are repeatable or can have multiple values, like the Contact header. The second method removes existing headers of this type and then adds a single header value.void removeHeader(Header)
Removes existing headers of this type.ListIterator getHeaderNames()
Returns all header names.ListIterator getUnrecognizedHeaders()
Returns header names for non-standard header types.Header getHeader(String)
ListIterator getHeaders(String)
Getters for specific headers. The second form returns all values of repeatable headers, or headers with multiple values, like the Contact header.void setContent(Object, ContentTypeHeader)
Sets the payload of the message, as well as the Content-Type header. Content-Length is also set if the type is a string, else usevoid setContentLength(ContentLengthHeader)
.byte [] getRawContent()
Object getContent()
Retrieves the payload of the message.void removeContent()
Empties the payload.void setContentLength(ContentLengthHeader)
ContentLengthHeader getContentLength()
void setContentLanguage(ContentLanguageHeader)
ContentLanguageHeader getContentLanguage()
void setContentEncoding(ContentEncodingHeader)
ContentEncodingHeader getContentEncoding()
void setContentDisposition(ContentDispositionHeader)
ContentDispositionHeader getContentDisposition()
Special payload-related header accessors. Rarely used.void setExpires(ExpiresHeader)
ExpiresHeader getExpires()
Manages the Expires header.void setSipVersion(String)
String getSipVersion()
Accessors for the SIP version element. Rarely used, defaults to SIP/2.0.Object clone()
Creates a copy of the message. Rarely used.Request
interface
Now let's glance through the Request
interface (sub-interface ofMessage
above):
String getMethod()
void setMethod(String)
Accessors for the method element. Can be any SIP method, including those in the constants of theRequest
interface: ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER, NOTIFY, SUBSCRIBE, MESSAGE, REFER, INFO, PRACK, and UPDATE.URI getRequestURI()
void setRequestURI(URI)
Accessors for the request URI, which is the first line of a SIP request. Typically, this is an instance ofSipURI
.Response
interface
The Response
interface also extends the Message
interface:
void setStatusCode()
int getStatusCode()
Accessors for the status code. This can be any SIP status code, including those in the constant members of theResponse
interface. Here are a few of them: RINGING (180), OK (200), BAD_REQUEST (400), and so on.void setReasonPhrase(String)
String getReasonPhrase()
Accessors for the human-readable explanation of the status code.Emmanuel Proulx is an expert in J2EE and SIP. He is a certified WebLogic Server engineer.
- [转]Introduction to JAIN SIP API part3_FINAL
- [转]Introduction to JAIN SIP API part1
- [转]Introduction to JAIN SIP API part2
- An Introduction to the JAIN SIP API
- Jain-sip
- JAIN SIP
- JAIN SIP instantmessaging学习
- jain-sip 开发文档
- Jain-sip-applet-phone
- JAIN SIP vs SIP Servlet
- An basic introduction to SIP
- JAVA-SIP协议栈 -- JAIN-SIP
- API Guides -> Introduction -> Introduction to Android
- Introduction to the Sockets API
- Introduction to Win32 API 翻译
- 用于呼叫控制的JAIN SIP
- useful URLs of JAIN SIP & Mobicents.
- jain-sip v1.2学习笔记
- 自定义控件之onLayout()
- Spring的自定装配与自动检测
- [转]Introduction to JAIN SIP API part2
- HTML5革命即将爆发
- 认识 ViewPager position
- [转]Introduction to JAIN SIP API part3_FINAL
- vs2015 MFC中动态显示图片
- [IDE]Netbeans 整合 Weblogic10
- HttpClient代理服务器配置
- Composer构建现代PHP帝国(二)——编写自己的Composer包
- dom4j生成xml中文问题
- APK系统签名
- [C#]介绍C#解析HTML的两种方法
- where can down OCI Demonstration Programs