Netty Learning Path (i) Netty+protocolbuffer implement simple message sending

Source: Internet
Author: User
Tags getmessage stub stringbuffer

Before we learn netty, we need to know what Netty is, Netty is a high-performance, asynchronous event-driven NIO framework that provides support for TCP, UDP, and file transfer, primarily providing asynchronous, event-driven network application frameworks and tools for rapidly developing high-performance, High-Reliability network server and client programs.
You can use Netty as a communication tool, and you can have it all involved in network communications, as well as Mina Netty.
Protocolbuffer is a Google format for data interchange, independent of language, platform-independent, and Google offers a variety of language implementations: Java, C #, C + +, go, and Python, each of which contains compilers for the language and library files. Protobuf can be treated as a carrier of encapsulated data.
Here's the syntax address for PROTOBUF.

http://blog.csdn.net/sylar_d/article/details/51325987

Actually, it's the domain that really works.
When we define the message, PROTOBUF provides 3 optional domains:
Required:message must contain at least one required field and must be assigned before serialization.
You need to include more than 0 optional domains in Optional:message.
Repeated: This field is used to save some variables that you want to set repeatedly, and these variables can be set up 0 times to multiple times. And the order is saved. (Used to set the array).
We can think of a message as a Java object, where required and option can be treated as constants, required cannot be null, option can be empty, and repeated can be viewed as a list.
Let's use a simple example.
First create the Protobuf file User.proto

Package test;

Option Java_package = "Com.zengame.proto.user";
Option Java_outer_classname = "Userproto";

Message req_updatesecuritypassword{
    Required String securitypassword = 1;
    Optional String Oldsecuritypassword = 2[default = ""];//Old password
} message

ans_recommendserver{
    required Recommendsvrid = 1;//recommended ServerID player may have information in other suits
} message

req_user{
    Required String username = 1;
}

This is the proto file, and the Java compiler is used to generate the code, which is specified below (note: Must be in the same directory):

protoc.exe-i=./--java_out=./proto  user.proto
Pause

When we use Proto, we serialize it and deserialize it, so I created a rpcmessage as the object that passed the message, and the code is as follows: Rpcmessage.java

Remember to add this tag and still implement the Serializable interface @Message public class Rpcmessage implements serializable{private static final long Seri
    Alversionuid = 1L; private int cmd; Used to store the protocol number private byte[] data;//used to store the PROTOBUF byte array private int seq; Message Queuing location Private byte type;//message type private transient Object obj;//This is temporarily useless, so add transient so that he does not need to serialize public int get
    CMD () {return cmd;
    public void setcmd (int cmd) {this.cmd = cmd;
    Byte[] GetData () {return data;
    public void SetData (byte[] data) {this.data = data;
    public int Getseq () {return seq;
    public void setseq (int seq) {this.seq = seq;
    Public byte GetType () {return type;
    The public void SetType (byte type) {This.type = type;
    Public Object Getobj () {return obj;
    public void Setobj (Object obj) {this.obj = obj;
       @Override public String toString () { Return "Rpcmessage [cmd=" + cmd + ", seq=" + seq + ", type=" + Type + "]"; }

}

Server Code Nettyserver.java

Serverbootstrap bootStrap = new Serverbootstrap (New Nioserversocketchannelfactory (
        Executors.newcachedthreadpool (), Executors.newcachedthreadpool ()); Bootstrap.setpipelinefactory (New Channelpipelinefactory () {@Override public channelpipeline GETP  Ipeline () throws Exception {//TODO auto-generated method stub Channelpipeline pipeline =
                Channels.pipeline (); Objectdecoder Objectdecoder = new Objectdecoder (1024 * 1024, Classresolvers.weakcachingconcurrentresolver (
                This.getclass (). getClassLoader ());
                Pipeline.addlast ("Decoder", New Protobufdecoder (UserProto.Ans_RecommendServer.getDefaultInstance ())); Pipeline.addlast ("Decoder", objectdecoder); The transfer object needs to decode Pipeline.addlast ("encoder", New Objectencoder ()) with object decoding; Transfer objects need to use object//pipeline.addlast ("Decoder", new PROTOBUFDEcoder (UserProto.Req_UpdateSecurityPassword.getDefaultInstance ()));
                Pipeline.addlast ("encoder", New Protobufencoder ()); Pipeline.addlast ("Handler", New Objectserverhandler ());
            The event handler needs to rewrite the return pipeline itself;

        }
        }); Bootstrap.bind (New inetsocketaddress (8000));

Server Processing Class Objectserverhandler.java

The public class Objectserverhandler extends simplechannelhandler{//Client Connection server executes @Override public void CHANNELC Onnected (Channelhandlercontext ctx, channelstateevent e) throws Exception {//channel store up Pl
    Ayermanager.addsession (100175, Ctx.getchannel ());  }//The server will execute @Override public void messagereceived (Channelhandlercontext ctx, messageevent e) When it receives the message
        Throws Exception {rpcmessage message = (rpcmessage) e.getmessage (); Switch (Message.getcmd ()) {case 10001:req_updatesecuritypassword ans = REQ_UPDATESECURITYPASSWORD.PA
            Rsefrom (Message.getdata ());
            SYSTEM.OUT.PRINTLN (message); System.out.println ("Securitypassword =" +ans.getsecuritypassword () + ", Oldsecuritypassword =" +
            Ans.getoldsecuritypassword ());
                                  Ans_recommendserver req = Ans_recommendserver.newbuilder (). Setrecommendsvrid (10001)   . build ();
            Playermanager.sendmessage (Message.getcmd (), Req.tobytearray (), 100175);
        Break
            Case 10002:req_user RSP = Req_user.parsefrom (Message.getdata ());
            SYSTEM.OUT.PRINTLN (message);
            System.out.println ("username=" + rsp.getusername ());
            req = Ans_recommendserver.newbuilder (). Setrecommendsvrid (10002). build ();
            Playermanager.sendmessage (Message.getcmd (), Req.tobytearray (), 100175);
        Break
        Default:break; }
    }
}

Client code Nettyclient.java

Clientbootstrap bootstarp = new Clientbootstrap (New Nioclientsocketchannelfactory (
        Executors.newcachedthreadpool (), Executors.newcachedthreadpool ()); Bootstarp.setpipelinefactory (New Channelpipelinefactory () {@Override public channelpipeline GETP  Ipeline () throws Exception {//TODO auto-generated method stub Channelpipeline pipeline =
                Channels.pipeline (); Objectdecoder Objectdecoder = new Objectdecoder (1024 * 1024, CLASSRESOLVERS.WEAKCACHINGCONCURRENTR
                Esolver (this. getclass (). getClassLoader ()));
                Pipeline.addlast ("Decoder", New Protobufdecoder (UserProto.Ans_RecommendServer.getDefaultInstance ()));
                Pipeline.addlast ("Decoder", objectdecoder);
                Pipeline.addlast ("encoder", New Objectencoder ()); Pipeline.addlast ("Handler", New OBjectclienthandler ());
            Client processing class return pipeline;

        }
        }); Bootstarp.connect (New Inetsocketaddress ("127.0.0.1", 8000));

Client-side processing class Objectclienthandler.java

public class Objectclienthandler extends Simplechannelhandler {@Override public void messagereceived (Channelhand
        Lercontext CTX, Messageevent e) throws Exception {rpcmessage message = (rpcmessage) e.getmessage (); Switch (Message.getcmd ()) {case 10001:ans_recommendserver Ans = Ans_recommendserver.parsefrom
            (Message.getdata ());
            SYSTEM.OUT.PRINTLN (message);
            System.out.println ("Recommendsvrid =" + Ans.getrecommendsvrid ());
        Break
            Case 10002:ans = Ans_recommendserver.parsefrom (Message.getdata ());
            SYSTEM.OUT.PRINTLN (message);
            System.out.println ("Recommendsvrid =" + Ans.getrecommendsvrid ());
        Break
        Default:break;  @Override public void channelconnected (Channelhandlercontext ctx, channelstateevent e) throws
    Exception {playermanager.addsession (100175, Ctx.getchannel ()); }
}

Client sends message code

int op = 0;
        Scanner in = new Scanner (system.in);
        StringBuffer sb = new StringBuffer ();
        Boolean flag = true;
            do{System.out.println ("Please enter the operation: 1 send message 2 disconnect");
            op = in.nextint ();
                Switch (OP) {case 1:system.out.print ("Please enter content to send message:");
                Sb.append (In.next () + "" +in.next ());
                string[] Value = sb.tostring (). Split (""); Req_updatesecuritypassword Req = Req_updatesecuritypassword.newbuilder ().
                                                Setsecuritypassword (Value[0]). Setoldsecuritypassword (value[1))
                . build ();
                Playermanager.sendmessage (10001,req.tobytearray (), 100175);
            Break
                Case 2:system.out.print ("Please enter the content to send the message:");
                Sb.setlength (0);
                Sb.append (In.next ());Req_user username = Req_user.newbuilder (). Setusername (Sb.tostring ())
                . build ();
                Playermanager.sendmessage (10002,username.tobytearray (), 100175);
            Break
                Default:PlayerManager.close (100175);
                SYSTEM.OUT.PRINTLN ("Connection closed!");
                flag =!flag;
            Break
        }}while (flag); SYSTEM.OUT.PRINTLN ("System shutdown");

Here I do one more step, store channel, file name is Playermanager.java

public class Playermanager {private static map<integer,channel> Sessionmap = new Concurrenthashmap<integer,

    Channel> (); public static void Addsession (int playerid, Channel Channel) {if (Sessionmap.containskey (playerID)) {if (Sessionmap.get (playerID) = = Channel)
            {return;
    } sessionmap.put (playerID, channel); public static void removesession (int playerid) {if (Sessionmap.containskey (playerID)) {Sessionma
        P.remove (playerID); }} public static Channel getsession (int playerid) {if (!sessionmap.containskey (playerID)) {RE
        Turn null;
    Return Sessionmap.get (playerID);
            public static void SendMessage (int cmd, byte[] data, int playerID) {if (Sessionmap.containskey (playerID)) {
            Rpcmessage message = new Rpcmessage ();
            Message.setcmd (CMD);
            Message.setseq (-1); Message.settyPE ((Byte)-1);
            Message.setdata (data);
            Sessionmap.get (playerID). write (message);
        SYSTEM.OUT.PRINTLN ("Send message succeeded."); } public static void close (int playerid) {if (Sessionmap.containskey (playerID)) {Sessionmap.
        Get (playerID). Close (); }
    }
}

Run results


Well, the whole general use should be, with these, I feel can realize a simple chat room system, haha
I would also like to say sorry, because I do not know Netty and NiO is not very deep, but I can recommend this article, is to explain NIO, personally feel very good explanation.

https://zhuanlan.zhihu.com/p/23488863

Summary: Personally feel for the Netty will only be preliminary use, the bottom of the implementation of what I do not know very well, the road of learning never cease.

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.