Mina.net sorting, mina.net
LZ has recently resigned and is idle. I plan to sort it out.
The company is doing e-commerce, and the CTO intends to develop the 2.0 System in java. LZ does not plan to do java at present, so it chooses to leave the company. The supply chain system of the last project in charge of the company before leaving the company.
The system is divided into three sub-systems:
1. Supply Chain work platform (user operation platform): Uses CS architecture and Sqlite for caching.
2 message center: the background program uses mina.net and scoket persistent connections to ensure service Message pushing, background message reminder, and the system caches the latest order.
3. WindowsService monitors the message center to ensure that the message center starts as the system starts.
Mina introduction:
Apache Mina Server is a network communication application framework. It is a communication framework based on TCP/IP and UDP/IP protocol stacks, mina can help us quickly develop high-performance and highly scalable network communication applications. Mina provides event-driven and asynchronous (the asynchronous IO of Mina uses Java NIO as the underlying support by default) programming Model of the operation.
Mina.net is the. net version of Apache Mina Server. It is mainly used for system persistent connection communication.
Installation:
PM> Install-Package Mina
Main objects of mina.net:
1. AsyncSocketConnector:Launch Link
2. IoSession:After the mina Link is created successfully, the client transmits the data of the service.
3. IoHandlerAdapter:Adapter class. Scalable
4. DemuxingProtocolCodecFactory:Build protocol coding Factory
Adapter methods:
1 MessageReceived: triggered when a message is received
2. triggered after MessageSent sends a message
3. triggered when SessionClosed closes the Session
4. triggered when Session is created by SessionCreated
5. triggered when ExceptionCaught encounters an exception
6. triggered when SessionIdleSession is idle
Implementation ideas:
Create mina Link:
Public void StartProcess (LoginContext config) {AsyncSocketConnector conne= new Mina. transport. socket. asyncSocketConnector (); // register the Protocol decoder factory connector. filterChain. addLast ("encoding", new ProtocolCodecFilter (new MyMinaCodecFactory (); // specify the Server IP address and port number connector. defaultRemoteEndPoint = new IPEndPoint (IPAddress. parse (MinaConfig. ip), MinaConfig. port); // initialize the message processing class var headerDic = CreateHeader (); // inherit the IoHandlerAdapter to build the adapter MinaMessageHandler headler = new MinaMessageHandler (config, connector, headerDic); connector. handler = headler; while (true) {try {// ClientHandler // create a link session = connector. connect (). await (). session; break;} catch (Exception ex) {_ Log. error (ex. message, ex); Thread. sleep (1000 );}}}
After the link is successfully established, trigger the SessionCreated method of the mina.net internal mechanism to log on to the user
public override void SessionCreated(Mina.Core.Session.IoSession session) { try { MyBaseMessage message = new LoginRequestMessage(ClientConfig.ClientAddr,ClientConfig.SharedSecret); (message as LoginRequestMessage).SetAutherString(); session.Write(message); } catch (Exception ex) { _Log.Error(ex.Message, ex); } finally { base.SessionCreated(session); } }
Override the MessageReceived method. After receiving the Server Message, process the corresponding event.
/// <Summary> /// triggered when a message is received -- process the message, send the processing result to the server /// </summary> /// <param name = "session"> </param> /// <param name = "message"> </ param> public override void MessageReceived (Mina. core. session. ioSession session, object message) {try {if (message is MyBaseMessage) {var m = message as MyBaseMessage; if (HeaderDic. keys. any (p => p = m. getCommandType () {var messageHeader = HeaderDic [m. getCommandType ()]; messageHeader. handle (session, m) ;}} catch (Exception ex) {_ Log. error (ex. message, ex);} finally {base. messageReceived (session, message );}}
Rewrite the SessionClosed event. When the session is closed, the server is notified, and the client has closed the link.
/// <Summary> /// triggered when the Session is closed-Send the closing message // </summary> /// <param name = "session"> </param> public override void SessionClosed (Mina. core. session. ioSession session) {try {while (true) {try {if (Connector! = Null) {if (! Connector. disposed) {session = Connector. connect (). await (). session; break;} else {break;} catch (Exception ex) {Thread. sleep (1000) ;}} catch (Exception ex) {_ Log. error (ex. message, ex);} finally {base. sessionClosed (session );}}
Override the ExceptionCaught method. When an exception occurs, close the link.
/// <Summary> /// triggered when an exception occurs, close the session and log on again. // </summary> /// <param name = "session"> </param> // <param name = "cause"> </param> public override void ExceptionCaught (Mina. core. session. ioSession session, Exception cause) {try {session. close (true); _ Log. error (cause. message, cause);} catch (Exception ex) {_ Log. error (ex. message, ex);} finally {base. predictioncaught (session, cause );}}
Override the SessionIdle method and test the heartbeat when the session is idle.
/// <Summary> /// when the Session is idle /// </summary> /// <param name = "session"> </param> /// <param name = "status"> </param> public override void SessionIdle (Mina. core. session. ioSession session, Mina. core. session. idleStatus status) {try {MyBaseMessage message = new DetectionMessage (); session. write (message);} catch (Exception ex) {_ Log. error (ex. message, ex);} finally {base. sessionIdle (session, status );}}
Build protocol codecs Factory
public class MyMinaCodecFactory : DemuxingProtocolCodecFactory { public MyMinaCodecFactory() { AddMessageEncoder(new MyMinaEncoder()); AddMessageDecoder(new MyMinaDecoder()); } }
Encoder factory, which converts the object serial number into bytes data
public class MyMinaEncoder : IMessageEncoder<MyBaseMessage> { public void Encode(IoSession session, MyBaseMessage message, IProtocolEncoderOutput output) { IoBuffer buf = IoBuffer.Allocate(12); buf.AutoExpand = true; var messageBytes = message.EncodeMessage(); buf.Put(messageBytes); buf.Flip(); session.Write(buf); } public void Encode(IoSession session, object message, IProtocolEncoderOutput output) { IoBuffer buf = IoBuffer.Allocate(12); buf.AutoExpand = true; if (message is MyBaseMessage) { var m = message as MyBaseMessage; var messageBytes = m.EncodeMessage(); buf.Put(messageBytes); buf.Flip(); } session.Write(buf); } }
Decoder factory, which converts bytes into objects
public class MyMinaDecoder : IMessageDecoder { public ILog _Log = LogManager.GetLogger("MessageHandler"); public MessageDecoderResult Decodable(IoSession session,IoBuffer input) { try { if (input.Remaining < CommandConfig.messageHeaderLength) { return MessageDecoderResult.NeedData; } var headerBytes = new byte[CommandConfig.messageHeaderLength]; for (int i = 0; i < CommandConfig.messageHeaderLength; i++) { headerBytes[i] = input.Get(i); } var lengthBytes = new byte[4]; var commandIdBytes = new byte[4]; var sequenceBytes = new byte[4]; Array.Copy(headerBytes, 0, lengthBytes, 0, 4); Array.Copy(headerBytes, 4, commandIdBytes, 0, 4); Array.Copy(headerBytes, 8, sequenceBytes, 0, 4); var messageLength = lengthBytes.ByteToUint();//Convert.ToInt32(Encoding.Default.GetString(headerBytes, 0, 4)); var messageCommand = commandIdBytes.ByteToUint();//(uint)Convert.ToInt32(Encoding.Default.GetString(headerBytes, 4, 4)); if (messageCommand==CommandConfig.connect || messageCommand == CommandConfig.connectResp || messageCommand == CommandConfig.terminate || messageCommand == CommandConfig.terminateResp || messageCommand == CommandConfig.notify || messageCommand == CommandConfig.notifyResp || messageCommand == CommandConfig.cmppActiveTest || messageCommand == CommandConfig.cmppActiveTestResp) { return MessageDecoderResult.OK; } return MessageDecoderResult.NotOK; } catch (Exception ex) { _Log.Error(ex.Message, ex); return MessageDecoderResult.NeedData; } }}
Conclusion:
Not many blogs are written. Do not touch it. Thank you.
Thank you for your advice and correction.