Use protobuf.net in Silverlight TCP Communication

Source: Internet
Author: User

Protobuf.net is the implementation of protobuf protocol on the. NET platform. It supports source. netProgram, Binary serialization of Silverlight and window phon7. this section describes how to use protobuf.net in Silverlight TCP communication. develop a communication protocol before achieving communication. It mainly describes protobuf.net serialized transmission formats and how to deserialize the obtained data.

The protocol description is divided into three parts: first, the total length of the message, followed by the message type name. The component creates the corresponding message object by the name, the end is the protobuf serialized data of the related object.

After the protocol is determined, you can proceed.CodeImplementation, because a Silverlight TCP component beetle. SL (Project address: http://beetlesl.codeplex.com/) has been written before; so it is OK to extend it directly on the basis. There are two tasks to be done: Implementing a message adapter and a protocol analyzer. Before implementation, you must reference the protobuf.net component at http://code.google.com/p/protobuf-net.

The message adapter implementation is as follows:
 1       Public   Class  Messageadapter: beetle. iMessage 2   {  3           Public   Object  Message  4   {  5               Get  ;  6               Set  ;  7   }  8           Static Dictionary < String , Type> mtypes = New Dictionary < String , Type> ( 256  );  9           Static Dictionary <type, String > Mnames = New Dictionary <type, String > ( 256  );  10          Public   Static   Void  Loadmessage (system. reflection. Assembly)  11   {  12               Foreach (Type T In  Assembly. gettypes ())  13   {  14 Protobuf. protocontractattribute [] Pc = (protobuf. protocontractattribute []) T. getcustomattributes ( Typeof (Protobuf. protocontractattribute ), False  );  15                   If (PC. length> 0  )  16   {  17                       String Name = T. Name;  18 Nameattribute [] NA = (nameattribute []) T. getcustomattributes ( Typeof (Nameattribute ),False  );  19                       If (PC. length> 0  )  20                       If (Na. length> 0  )  21   {  22 Name = Na [ 0  ]. Name;  23  }  24   Mtypes. Add (name, t );  25   Mnames. Add (T, name );  26   }  27   }  28   }  29           Public   Static   Void Send (beetle. tcpchannel channel,Object  Message)  30   {  31 Messageadapter MA = New  Messageadapter ();  32 Ma. Message = Message;  33   Channel. Send (MA );  34   }  35           Public  Void  Load (beetle. bufferreader)  36   {  37               String Type = Reader. readstring ();  38               Byte [] DATA = Reader. readbytearray ();  39               Using (System. Io. Stream stream = New System. Io. memorystream (data, 0 , Data. Length ))  40   {  41 Message = protobuf. Meta. runtimetypemodel. Default. deserialize (stream, Null  , Mtypes [type]);  42   }  43               44   }  45           Public   Void  Save (beetle. bufferwriter writer) 46   {  47   Writer. Write (mnames [message. GetType ()]);  48               Byte  [] Data;  49               Using (System. Io. Stream stream = New  System. Io. memorystream ())  50   {  51  Protobuf. Meta. runtimetypemodel. Default. serialize (stream, message );  52                  53 Data = New   Byte  [Stream. Length];  54 Stream. Position = 0  ;  55 Stream. Read (data, 0  , Data. Length );  56   57  }  58   59   Writer. Write (data );  60              61   62   }  63 }

The implementation of the entire process is relatively simple, that is, writing serialized information into bufferwriter based on the content of the Protocol, and obtaining the message from bufferreader in the same way.

Implementation of subcontractors

Beetle. SL already provides a package based on the header Description Size, so the implementation is simpler.

     Public   Class  Protobufheadsizepackage: beetle. headsizeofpackage { Public  Protobufheadsizepackage (){}  Protected   Override   Void  Writemessagetype (iMessage MSG, bufferwriter writer ){}  Protected   Override IMessage readmessagebytype (bufferreader reader, Out   Object  Typetag) {typetag = "  Messageadapter "  ;  Return   New  Messageadapter ();}} 

To easily define connections, tcpchannel is inherited to implement a protobufchannel.

 
Public ClassProtobufchannel: tcpchannel {PublicProtobufchannel ():Base(NewProtobufheadsizepackage ()){}}

After completing the following work, you can use protobuf.net to process objects in Silverlight TCP communication. Below are some simple information.

[Protocontract]  Public   Class  Search {[protomember (  1  )]  Public   String CompanyName { Get ; Set  ;} [Protomember (  2  )]  Public   String City {Get ; Set  ;} [Protomember (  3  )]  Public   String Region { Get ; Set  ;} [Protocontract]  Public   Class  Searchresult {[protomember (  1  )] Public List <customer> MERs {  Get  ;  Set  ;} [Protocontract]  Public   Class  Getcustomerorders {[protomember (  1  )]  Public   String  Customerid { Get  ;  Set  ;} [Protocontract]  Public   Class  Customerorders {[protomember (  1  )]  Public Ilist <order> Orders {  Get  ;  Set  ;}} 

After the message is set, you can define the connection.

 
PrivateProtobufchannel mchannel =NewProtobufchannel ();Private VoidUsercontrol_loaded (ObjectSender, routedeventargs e) {messageadapter. loadmessage (This. GetType (). Assembly); mchannel. Connected+ =Onconnected; mchannel. disposed+ =Ondisposed; mchannel. Receive+ =Onreceive; mchannel. Error+ =Onerror ;}

After the connection is created, bind related events. The main events include connection success, connection release, connection handling error, and Data Receiving Event. After defining these events, you only need to call a simple connect method to connect to the TCP Service of the specified IP port.

 
Private VoidCmdconnect_click (ObjectSender, routedeventargs e) {mchannel. Connect (txtip. Text,4520);}

After the connection, you can directly use the channel to send protobuf.net serializable objects.

Private VoidCmdsearch_click (ObjectSender, routedeventargs e) {packages. Search search=NewPackages. Search (); search. companyName=Txtcompany. Text; messageadapter. Send (mchannel, search );}

Data events can be output based on different message types.

         Private   Void Onreceive ( Object  Sender, eventchannelreceiveargs e) {messageadapter Adapter =(Messageadapter) E. message;  If (Adapter. Message Is  Packages. searchresult) {packages. searchresult = (Packages. searchresult) Adapter. message;  This . Dispatcher. begininvoke () => {Dgcustomers. itemssource = Searchresult. MERs ;});}  Else   If (Adapter. MessageIs  Packages. customerorders) {packages. customerorders orders = (Packages. customerorders) Adapter. message;  This . Dispatcher. begininvoke () => {Dborders. itemssource = Orders. Orders ;});}} 

The preceding is a simple data query example.

Demo

Specific Code can go to http://beetlesl.codeplex.com/get

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.