Data transfer Protocol of socket Development framework

Source: Internet
Author: User

Data transfer Protocol of socket Development framework

In the previous essay, "Framework Design and analysis of socket development framework", this paper introduces the overall idea of the whole socket development framework, summarizes and abstracts the base classes of each level, and has achieved the purpose of reusing and simplifying code. This article continues to analyze the important part of the protocol design, the design of the message protocol, as well as the data unpacking and encapsulation of the relevant introduction, so that we better use the characteristics of the socket at a higher level.

1. Protocol Design Ideas

The encapsulation and unpacking of the socket transmission message, most of the socket applications, mostly based on sequential location and byte length to determine the relevant content, such processing can be very good to reduce the size of the data, but these processing for us to analyze complex protocol content, it is a disaster. It is very easy to understand the difficulty of a developer who has tracked such an agreement, and if the location of the protocol changes or requires special processing, it is very error-prone, and most of the code is riddled with numerical variables in many places, and the analysis and understanding are very inconvenient. With the development of network technology, sometimes the transmission of data slightly larger, loss of some bandwidth to transfer data, but can be multiplied to improve the efficiency of the development process is our goal worthy of pursuit. For example, the current Web API in a variety of devices in the way, relative to the socket message, it itself in the data size is not dominant, but the convenience and efficiency of development is well known.

Reference to the characteristics of the Web API to consider the transmission of the socket message, if the overall content, the socket application also uses a more flexible message format, such as JSON format to transfer data, then we can be very good message encapsulation and message unpacking to resolve two parts, To the third-party JSON parser, we only need to focus on the specific message processing logic can be, and for the extension of the protocol, like JSON, can be free and flexible, so instantaneous, the whole world will be very quiet.

For the security and integrity of the socket message, we can use the RSA Public key cryptography system for encryption processing. Platform through the sending platform RSA public key message to the terminal to inform their RSA public key, terminal reply to the terminal RSA public key message, so that the platform and terminal messages, can be encrypted by their own private key, so that the other party based on the received public key decryption can be, although the length of encrypted data will increase a lot, However, for high security requirements, it is also necessary to adopt this approach.

For the integrity of the data, the traditional CRC check code is not much use, because our data will not be lost in part, and we should be concerned about whether the data has been tampered with, I think of the public API interface design, they have a secure signature of the encrypted string, That is, the content of the same rules of encryption processing, and then compare the two signature content is consistent. However, for asymmetric encrypted transmissions, this validation of data integrity can also be unnecessary.

As described earlier, we can refer to the way the Web API, in JSON format as our transmission of content, convenient serial number and deserialization, so we can greatly reduce the socket protocol analysis difficulty and error, reduce the difficulty of socket development and improve the speed of development applications. So how do we design this format?

First we need to define the starting and ending identities for the socket message, and the middle part is the JSON content of the entire generic message. In this way, a complete socket message content, in addition to the start and end of the identity bit, the remainder is a JSON-formatted string data.

We are prepared to design the entire JSON string content as needed, and the best design is more general, so that we can carry more data information.

2. Protocol Design Analysis and evolution

Referring to the API delivery message definition, I designed the following message format, including the delivery user ID, send user ID, message type, creation time, and a common content field, this common field should be another message entity JSON string, so that our entire message format does not change, But the specific content is different, we call this object class Basemessage, characters commonly used paragraph is as follows.

The content field above is used to host specific message data, it will be based on different message types, different content, and these are specific entity classes serialized as JSON strings, we have designed these classes for convenience, the base class, That is, the socket passes data to the entity class base class baseentity.

We inherit from the different request and reply messages. To make it easier for us to convert it to the basemessage message we need, add an identifier for it to the Msgtype protocol type, and add the Packdata method to convert the entity class to a JSON string.

For example, we generally request requests and answer response message objects, are inherited from the baseentity, we can put these two kinds of message objects in a different directory for easy management.

An example of an inheritance relationship is shown below.

Where subclasses can use the Packdata method of the base class, the direct sequence number is a JSON string, the Packetdata function is mainly used to assemble the object to be sent Basemessage, the function code is as follows:

        <summary>///        package data for sending//</summary>//        <returns></returns>        Public Basemessage Packdata ()        {            Basemessage info = new Basemessage ()            {                Msgtype = this. Msgtype,                Content = this. SerializeObject ()            };            return info;        }

Sometimes we need to construct the returned reply message based on the requested information, because the Sender ID and the delivery ID need to be reversed.

        <summary>        ///package data Send (copy request part of data)///</summary>//        <returns></returns> Public        basemessage Packdata (basemessage request)        {            Basemessage info = new Basemessage ()            {                Msgtype = this. Msgtype,                Content = this. SerializeObject (),                callbackid = Request. Callbackid            };            if (!string. IsNullOrEmpty (Request. Touserid))            {                info. Touserid = Request. Fromuserid;                Info. Fromuserid = Request. Touserid;            }            return info;        }

The data entity object that is requested by the login is introduced, it inherits from BaseEntity, and the corresponding message type can be specified as well.

    <summary>///    Login Request message entity///    </summary> public    class authrequest:baseentity    {        # Region field Information///<summary>//user account///        </summary> public        string UserId {get; set;}        <summary>///user password///        </summary> public        string Password {get; set;}        #endregion        ///<summary>///default constructor///</summary> public authrequest ()        { This            . Msgtype = datatypekey.authrequest;        }        <summary>///parametric constructors///</summary>//        <param name= "userid" > User account </param >        //<param name= "password" > User password </param> public        authrequest (string userid, String password ): This ()        {this            . UserID = userid;            This. Password = Password;        }    }

So our message content is very simple, convenient for us to pass and deal with.

3. Receiving and sending messages

Before we introduced some base classes, including the socket client base class, and the base class design of data reception, these packages can provide me with good convenience.

In the above basesocketclient, in order to be able to parse the socket message of the different protocols and convert it to the base class object we need, we introduce a parser messagesplitter, the main function of this class is to parse the byte data, And the entire message is extracted.

So we've designed the code for the class definition of basesocketclient as follows.

    <summary>    ///Basic Socket operation class, providing connection, disconnection, receiving and sending related operations. //</summary>//    <typeparam name= "Tsplitter" > corresponding message resolution Class, inherited from Messagesplitter</typeparam> Public    class basesocketclient<tsplitter>  where Tsplitter:messagesplitter, new ()

Messagesplitter object, to deal with the low-level protocol resolution, we described earlier in addition to the protocol header and the end of the protocol, the rest is a JSON, then it needs to be based on this rule to implement byte-to-object conversion.

The first step is to split the byte data and add a complete piece of data to the list for subsequent processing.

At the end of this section, we need to extract the cached direct data to a specific object.

Rawmessage msg = this. Convertmessage (Msgbuffercache, from);

The approximate rules for this conversion are shown below.

This way, after we receive the message, we can use the Tsplitter object to parse it, as shown below is the processing of the socket message.

                    Tsplitter splitter = new Tsplitter ();                    Splitter. Initparam (this. Socket, this. Startbyte, this. Endbyte);//Specify Delimiter for unpacking                    Splitter. DataReceived + = splitter_datareceived;//If there is complete packet processing, then the event notification

After the data receives and obtains the direct data object of a message, we further convert the direct object to a specific message object.

        <summary>///        Message split class received message events///</summary>//        <param name= "Data" > Original Message Object </param >        void splitter_datareceived (rawmessage data)        {            Receivepackcount + = 1;//Increase the number of packets received            Onreadraw (data );        }        <summary>///The        processing after receiving data, can be overloaded with sub-class///</summary>//        <param name= "Data" > Original Message object (containing raw byte data) </param>        protected virtual void Onreadraw (rawmessage data)        {            // Provides default package handling: Assume that the entire content is JSON, and/            /If you need to work with a custom message body, you need to override the Onreadmessage method in subclasses.            if (data! = NULL && data. Buffer! = null)            {                var json = encodinggb2312.getstring (data). Buffer);                var msg = jsontools.deserializeobject<basemessage> (JSON);                Onreadmessage (msg);//To Subclass overloading            }        }

At a higher level of data parsing, we can work with object-level messages.

For example, when we receive the message, it resolves itself to an entity class Basemessage, then we can take advantage of Basemessage's message content, or it can convert its content contents to the corresponding entity class for processing, as shown in the following code is the processing after receiving the object.

        void Textmsganswer (Basemessage message)        {            var msg = string. Format (Message from ' {0} ': ', '. Fromuserid);            var request = jsontools.deserializeobject<textmsgrequest> (message. Content);            if (Request! = null)            {                msg + = string. Format ("{0}  {1}", request. message, message. Createtime.inttodatetime ());            }            Messageutil.showtips (msg);            Portal.gc.MainDialog.AppendMessage (msg);        }

For the message processing, we can cite an example, if the client needs to get a list of online users after landing, then you can send a request command, then the server needs to follow this command to return the list information to the terminal, as shown in the following code.

        <summary>///        respond to client requests for user list///</summary>//        <param name= "Data" > Specific Message Object </ param>        private void userlistprocess (Basemessage data)        {            Commonrequest request = Jsontools.deserializeobject<commonrequest> (data. Content);            if (Request! = null)            {                log.writeinfo (string. Format ("############\r\n{0}", data. SerializeObject ()));                list<clistitem> list = new list<clistitem> ();                foreach (Clientofshop client in Singleton<shopclientmanager>. Instance.LoginClientList.Values)                {                    list. ADD (new Clistitem (client). Id, client. Id));                }                Userlistresponse response = new Userlistresponse (list);                Singleton<shopclientmanager>. Instance.addsend (data. Fromuserid, Response. Packdata (data), true);            }        }

Data transfer Protocol of socket Development framework

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.