Analysis of EMPP Protocol of China Mobile Enterprise SMS Communication Platform

China Mobile Enterprise Information Communication Address: http://sms.sh.chinamobile.com/qxt/index.jsp

    Recently, I will design SMS sending for a project in hand. After a brief analysis, China Mobile Enterprise Information Communication will be used as a tool in the end. . A brief summary:

1. Select the SMS sending scheme
1. MAS method: It is

    necessary to use hardware equipment, and also to install and configure the software, which is very cumbersome and expensive.
    Listening to a project using a mas machine, the delay is relatively serious, from a few minutes to even more than ten minutes. Of course it may be that the equipment is old.
    give up!

2.
    The things that Ali is bigger than Ali are of course good. The information on the website is very complete, but no one has used the project of colleagues. The main problem is that the sender's mobile phone number cannot be fixed.
The number received and displayed on the mobile terminal is the regular number display rule starting with 106:
a. Number = channel number + extension code;
b. Under the irresistible factors such as channel instability, network jitter and power failure in the computer room, in order to ensure the arrival rate and the arrival time, the channel will be automatically switched, and the channel number will change.
    I don't know if the number will remain the same between the split text messages. I don't know if it is possible to sacrifice the reach rate and time to ensure that the displayed number remains unchanged?

3. EMPP
    provides EMPP API, and there are related documents and simple examples.

    In the end, I didn't know why I chose to move, but I researched EMPP anyway.

2. Mobile EMPP
    There is an enterprise information communication platform. Enterprise users log in to the mobile platform through the account assigned to them, and can send text messages, receive status, and receive replies. Own applications can use these functions using the provided EmppAPI.
    It is estimated that the text messages sent through the API can also be seen by logging in to the platform.

    After reading Ali's DUBBO, the code is much simpler to look at EMPP, and it does not need NIO. An EMPP protocol is designed on the TCP protocol, which is simply programmed with socket, mainly to convert the information object into a designed BYTE[] and send it to the platform. The platform returns the BYTE[] stream, and then parses the object. Usually there are design of message header and message body.
   
    1. EmppApi.java and RecvListener.java
    are the core classes used. Once EmppApi connects to a remote host, two threads will be started:

RecvThread: The purpose is to continuously receive information from the host and generate EMPPObject objects .
buffer=connection.receive(12);
buffer.appendBuffer=connection.receive(length - 12);
EMPPObject.createEMPP(buffer);
EMPPObject actually has many specific types, including various situations of communication with the host, which are divided into emppRequest and There are two categories of emppResponse.

SendActiveThread: The goal is to continuously send detection objects and maintain a tcp connection to the host.
connection.send(emppActiveTest).

    Whether it is sending or receiving, it is handled through the input and output streams on the socket, which is relatively simple.

    2. Listener RecvListener
EmppApi emppApi = new EmppApi();
RecvListener listener = new RecvListener(emppApi);
EMPPConnectResp response = emppApi.connect(host, port, accountId,
password, listener);

     simply look at the above relationship, the big BOSS first Birth, regenerate a secretary, and at the same time pass the BOSS to it, that is, configure the secretary to the BOSS. When the boss is working, pass the secretary in.
     What is the use of a secretary? Isn't there a thread inside the BOSS that has been receiving it all the time? After receiving the information, let the secretary handle it. The interesting thing is the OnClosed method. When a disconnection message is received, the secretary's job is to create a new secretary and assign it to the BOSS for reconnection.

RecvListener listener = new RecvListener(emppApi)
...
emppApi.reConnect(listener);

    In addition, there is a ByteBuffer class, which is very convenient when dealing with byte[].

    3. The more detailed technologies related to the protocol are:
    Copy: System.arraycopy. This is a native method.
    Shift: intBuf[3] = (byte)(data & 255); intBuf[2] = (byte)(data >>> 8 & 255);
    Convert: getBytes(encoding).

Third, nio and netty
    see that the technology in this EMPPAPI is too old, and the source code is from 2008. A brief review of nio.
    nio is a new version of TCP communication editing technology io processing, non-blocking io, netty is a programming framework based on nio.
    The old io is that the server creates a thread when it receives a TCP connection. After the client sends the information, the thread waits to read the channel on the socket. Both processes are blocking threads. Of course, it has nothing to do with the client sending information. If you want to send it, you can send it, and you can write it if you want to write. It's just that the read is blocked, and it will wait until the data arrives (or time out) before returning.
    Both the server and the client are blocked while waiting. It's just because it's blocked, what should I do? Then design a unified thread (public server) to listen, and then notify me when there is a result, and I don't have to watch it all the time, just do what I want. Kind of like asynchronous communication, kind of like callbacks.

    For the client:
      a. First generate a selector (public server), and then register this channel with the server.
        this.selector = Selector.open(); 
        // The client connects to the server. In fact, the method execution does not realize the connection. It needs to be called in the listen() method. 
        //Use channel.finishConnect(); to complete the connection 
        channel.connect(new InetSocketAddress(ip,port)); 
        //Bind the channel manager to the channel and register the SelectionKey.OP_CONNECT event for the channel. 
        channel.register(selector, SelectionKey.OP_CONNECT); 
        The channel can now do other things...

      b. If the registration happens
        SocketChannel channel = (SocketChannel) key.channel(); If
        the relevant channel is found, you can continue Feedback on this matter.
        channel.write(ByteBuffer.wrap(new String("Sent a message to the server").getBytes()));

      For the server:
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        The previous sentence is also registered, then Can do other things...
        SocketChannel is the channel generated by serverChannel accepting good connections. Can it be recorded in the map by user, and when the server wants to actively send information, it can query the map to find the available channels to use?     The former ServerSocketChannel/ SocketChannel
        is used to receive incoming requests (that is, the first handshake), while the latter is responsible for specific business processing (that is, after the first handshake is successful, it will be handed over to it for processing)



.
The source code of empp, record some knowledge:
1. Protocol design
  The protocol includes header and body parts. The header includes three parts, the serial number (same as the request and return), the total length of the information, and the information type. A total of 12 bytes, this is fixed. body is not fixed.

2. Protocol serialization and serialization
   2.1 Convert the information object into byte[12+body.length] before sending
    public ByteBuffer getData()
        throws ValueNotSetException
    {
        ByteBuffer bodyBuf = new ByteBuffer();
        bodyBuf.appendBuffer(getBody() );
        setCommandLength(bodyBuf.length() + 12);
        ByteBuffer emppBuf = getHeader();
        emppBuf.appendBuffer(bodyBuf);
        return emppBuf;
    }
    where getBody() is to spell out all the attributes of the information into a long buffer, such as where One: buffer.appendCString(feeTermId, 32);
    After that, write with socket stream: outputStream.write(data.getBuffer(), 0, data.length());

   2.2 After receiving, convert byte[] into object information object
    public EMPPObject receive(long timeout)//corresponding method
    buffer = connection.receive(12);//First take the first 12 bytes
    ByteBuffer bfBody = connection.receive(length - 12);
    buffer.appendBuffer(bfBody);
    return EMPPObject.createEMPP(buffer);
    //After the information object is newly created according to the header information, after reading the byte[] of the corresponding length one by one, set the properties of the object.
    setSrcTermId(buffer.removeCString(21));

    2.3 I have a question: why not use the java object to write the stream directly? ? ? Efficiency?

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326333438&siteId=291194637