Netty + PROTOBUF uses reflection to implement multiple types of transmission

Source: Internet
Author: User

This article is a follow-up to this article (https://www.cnblogs.com/Binhua-Liu/p/5577622.html), This article describes the protobuf of adding a layer of headers from the PROTOBUF in the Netty framework can only have a limited object. In Mushroom Street open source TEAMtalk, also added a header, according to the type of operation in the header, the corresponding logical processing operation.

Here is our configuration file for implementing the logic of Decodebody in Servercustomdecodehandler. Protobuf the generation of objects by reflection requires the use of the "Package $ class" form.

<?XML version= "1.0" encoding= "UTF-8"?><Decodetypes>    <Decodetypetype= "Com.zywj.protobuf.out.imbase$messagecmdid"Val= "Cid_msg_data_value"class= "Com.zywj.protobuf.out.immessage$msgdata" />    <Decodetypetype= "Com.zywj.protobuf.out.imbase$othercmdid"Val= "Cid_other_heartbeat_value"class= "Com.zywj.protobuf.out.imother$heartbeat" /></Decodetypes>

The work of reading XML is placed in the server and declared as private static. Here is a map variable generated based on my own logic.

Private StaticMap parsexmldata (String xmlfilepath) {Saxreader reader=NewSaxreader (); Document Doc=NULL; Try{doc= Reader.read (NewFile (Xmlfilepath)); } Catch(documentexception e) {e.printstacktrace (); } Element Root=doc.getrootelement (); Map<String,Map> Map =NewHashmap<>();  for(Iterator i_action=root.elementiterator (); I_action.hasnext ();) {Element e_action=(Element) i_action.next (); Iterator it=E_action.attributeiterator (); Attribute Key=(Attribute) it.next (); String type=Key.getvalue (); Map<string, string> inner =NewHashmap<>();  while(It.hasnext ()) {Attribute Attribute=(Attribute) it.next ();            Inner.put (Attribute.getname (), Attribute.getvalue ());        } map.put (type, inner); }        returnmap; }

The work of Servercustomdecodehandler's decodebody is to generate objects from the data in the map by reflection, and it is necessary to determine if the current object's enum value is equal to CommandID, if found, The corresponding Protobuf object is generated.

     PublicMessagelite Decodebody ( ShortCommandId,byte[] Array,intOffsetintLengththrowsException {Map<string, map> decodemap =Server.decodemap;  for(Map.entry<string, map>Entry:decodeMap.entrySet ()) {Map<string, string> m =Decodemap.get (Entry.getkey ()); Class Clazz=Class.forName (Entry.getkey ()); Field F= Clazz.getfield (M.get ("Val")); if((int) F.get (clazz) = =commandId) {Class CLS= Class.forName (M.get ("Class")); Method Method= Cls.getmethod ("Getdefaultinstance"); Object obj= Method.invoke (CLS,NULL); Method= Cls.getmethod ("Getparserfortype"); Obj= Method.invoke (obj,NULL); return((parser<messagelite>obj). Parsefrom (array, offset, length); }        }        return NULL; }

Here, is not finished, because Serverhandler inside is passed in is the object MSG, so also use instanceof to determine if it is protobuf objects. So again it's an XML, and then reflection.

<?XML version= "1.0" encoding= "UTF-8"?><Msgtypes>    <Msgtypetype= "Com.zywj.protobuf.out.immessage$msgdata"class= "Com.zywj.server.LogicHandler"Method= "Handlemsgdata" />    <Msgtypetype= "Com.zywj.protobuf.out.imother$heartbeat"class= "Com.zywj.server.LogicHandler"Method= "Handleheartbeat" /></Msgtypes>

The channelRead0 in Serverhanlder is changed into

@Override Public voidChannelRead0 (Channelhandlercontext ctx, Object msg)throwsException {Map<string, map> dispatchmap =Server.dispatchmap;  for(Map.entry<string, map>Entry:dispatchMap.entrySet ()) {Class Clazz=Class.forName (Entry.getkey ()); if(Msg.getclass (). IsAssignableFrom (Clazz)) {Map<string, string> m =Dispatchmap.get (Entry.getkey ()); Class Clazzlogic= Class.forName (M.get ("Class")); Method Handle= Clazzlogic.getdeclaredmethod (M.get ("method"), Channelhandlercontext.class, Object.class);                Handle.invoke (Clazzlogic.newinstance (), CTX, msg);  Break; }        }    }

Severcustomencodehandler is the same way, not to repeat.

Here, we use reflection to put too much if...else in the above article ... To avoid it.

Finally, I think there will be too much reflection (cyclic reflection, Time complexity O (n)), and the amount of code actually does not decrease, just transferred to the XML, the biggest advantage is to reduce the coupling bar.

Netty + PROTOBUF uses reflection to implement multiple types of transmission

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.