Protocol codec is the object you need to focus on when using Mina, because the data transferred in the network is binary data (byte), and you are targeting Java objects in your program, this requires you to encode the Java objects into binary data when sending the data, When data is received, the binary data is decoded as a Java object (note that this is not a serialization and deserialization of Java objects).
1, Encoding: encoding is the normal object of the property content in turn into binary object property content process.
2. Decoding: The process of converting binary object fields into Normal object property field content.
1, Codec factory: Provide coding and decoding implementation of the call portal
The protocol codec in Mina is constructed by the filter protocolcodecfilter, which requires a protocolcodecfactory to construct the filter,
The following two methods are available in Protocolcodecfactory:
Public interface Protocolcodecfactory {
Protocolencoder Getencoder (iosession session) throws exception;// Protocolencoder is a custom encoder to implement the interface
Protocoldecoder Getdecoder (iosession session) throws exception;// Protocoldecoder is the interface that the custom decoder is to implement
}
Take the message-passing factory for example:
Codec generation factory public
class Messageprotocolcodecfactory implements Protocolcodecfactory {
private Protocolencoder encoder;
Private Protocoldecoder decoder;
Public Messageprotocolcodecfactory ()
{This
(Charset.forname ("UTF-8"));
}
Public messageprotocolcodecfactory (Charset Charset)
{
encoder = new Messageencoder (Charset);
decoder = new Messagedecoder (charset);
}
@Override public
protocoldecoder getdecoder (iosession arg0) throws Exception {return
decoder;
}
@Override public
protocolencoder getencoder (iosession arg0) throws Exception {return
encoder;
}
}
2. Message Transfer object: The entity object that loads the transmitted data
The following is sample code: (Analog mobile phone information codec, message format: message header, sender, receiver, content length, content information)
Msgobject.java: Message entity classes
public class Msgobject {
//sender
private String sender;
Recipient
Private String receiver;
Information content
private String content;
Public String Getsender () {return
sender;
}
public void Setsender (String sender) {
this.sender = sender;
}
Public String Getreceiver () {return
receiver;
}
public void Setreceiver (String receiver) {
this.receiver = receiver;
}
Public String getcontent () {return
content;
}
public void SetContent (String content) {
this.content = content;
}
}
3. Message encoder: Messageencoder.java, this class implements Protocolencoder or inherits from Protocolencoderadapter
Message encoder public class Messageencoder extends Protocolencoderadapter {private Charset Charset;
Public Messageencoder (Charset Charset) {this.charset = Charset;
@Override public void Encode (iosession sessions, Object message, protocolencoderoutput out)
Throws Exception {msgobject msg = (msgobject) message;
Generate character encoder Charsetencoder Charsetencoder = Charset.newencoder ();
Get to send object attribute content, prepare to encode String status = "M sip:wap.fetion.com.cn sip-c/2.0";
String sender = Msg.getsender ();
String receiver = Msg.getreceiver ();
String content = Msg.getcontent ();
Open a cache space, set to auto resize Iobuffer iobuffer = iobuffer.allocate (100);
Iobuffer.setautoexpand (TRUE);
The information to be sent into the cache space//message header iobuffer.putstring (status + "\ n", Charsetencoder);
Message sender iobuffer.putstring ("S:" + sender + "\ n", Charsetencoder); Message receptionPerson Iobuffer.putstring ("R:" + receiver + "\ n", Charsetencoder);
Message content Length Iobuffer.putstring ("L:" + content.getbytes (CharSet). length + "\ n", Charsetencoder);
Message contents iobuffer.putstring (content + "\ n", Charsetencoder);
The encoded information has been put into the iobuffer for writing back to Iobuffer.flip ();
Out.write (Iobuffer);
}
}
4, Message decoder: Messagedecoder.java, this class implements Protocoldecoder or inherits from Protocoldecoderadapter
Message decoder public class Messagedecoder extends protocoldecoderadapter{private Charset Charset;
Public Messagedecoder (Charset Charset) {this.charset = Charset; @Override protected Boolean Dodecode (iosession session, Iobuffer in, protocoldecoderoutput out) throws Ex
ception {Charsetdecoder Chardecoder = Charset.newdecoder ();
Iobuffer buffer = iobuffer.allocate. Setautoexpand (True);
Receive decoded message String status = "";
String sender = "";
String receiver = "";
String Contentlen = "";
String content = "";
int textlinenumber = 1;
int columnnumber = 0;
If there is a message in the buffer while (in.hasremaining ()) {byte BT = In.get ();
Buffer.put (BT);
NewLine if (BT = && Textlinenumber < 5) {columnnumber++; if (Textlinenumber = = 1) {buffer.Flip ();
Status = Buffer.getstring (ColumnNumber, Chardecoder);
Status = Status.substring (0, Status.length ()-1);
ColumnNumber = 0;
Buffer.clear ();
} if (Textlinenumber = = 2) {buffer.flip ();
Sender = Buffer.getstring (ColumnNumber, Chardecoder);
Sender = sender.substring (0, Sender.length ()-1);
ColumnNumber = 0;
Buffer.clear ();
} if (Textlinenumber = = 3) {buffer.flip ();
Receiver = buffer.getstring (ColumnNumber, Chardecoder);
Receiver = receiver.substring (0, Receiver.length ()-1);
ColumnNumber = 0;
Buffer.clear ();
} if (Textlinenumber = = 4) {buffer.flip (); Contentlen = buffer.getstring (ColumnNumber, Chardecoder);
Contentlen = contentlen.substring (0, Contentlen.length ()-1);
ColumnNumber = 0;
Buffer.clear ();
} textlinenumber++;
else if (Textlinenumber = 5) {columnnumber++;
if (ColumnNumber = = Long.parselong (Contentlen.split (":") [1])) {buffer.flip ();
Content = buffer.getstring (ColumnNumber, Chardecoder);
textlinenumber++;
Break
} else {columnnumber++;
} msgobject smsobject = new Msgobject ();
Smsobject.setsender (Sender.split (":") [1]);
Smsobject.setreceiver (Receiver.split (":") [1]);
Smsobject.setcontent (content);
Out.write (Smsobject);
return false; }
}
5, Mina codec need to know some things
1), it is best to understand the reading operation of the next Mina Iobuffer.
2, in the filter to call these codecs for object transmission, server-side and the client's main program written.
3), consider whether the batch implementation of the object decoding
The decoding in the above message decoder (Messagedecoder.java) considers that the message is sent from the server at once, but sometimes the message may not be sent from the server one at a time, but it is divided into batches several times, and then the Decode () method of the decoder is repeated. Then the state variables Textlinenumber and columnnumber are reset, so the state variables are saved. You might think of saving a state variable in a member variable of a decoder, but Mina does not guarantee that each call to the decode () method is the same thread, so the state variable is not thread safe. So to save the state variable to iosession, because Iosession uses a synchronized HashMap to save the object (the client and server-initiated sessions are not the same process, so the session is not the same one, This can be manifested as Mina is an event-driven asynchronous API.
The following is the saving of state variables in iosession:
Holds the key value of the data state object
Private Final Attributekey context = new Attributekey (GetClass (), "context");
Objects that save data through Iosession.setattribute and Iosession.getattribute
private Msgcontext getcontext (iosession {Msgcontext Context
= (Msgcontext) session.getattribute (context);
if (Null = context) {Context
= new Msgcontext ();
Session.setattribute (context, context);
}
return context;
}