As a high-performance asynchronous network development framework, Netty can be used as a framework for the development of various services.
A project of the previous time involves the acquisition of real-time data of hardware equipment, using Netty as the implementation framework of the acquisition service, and using RABBITMQ as the communication message queue for the acquisition service and each other module, the whole service framework diagram is as follows:
1, device TCP message parsing:
TCP communication is used between nettymqserver and device devices, and the message parsing of TCP messages can use Lengthfieldbasedframedecoder (message header and message body), which can solve the problem of "sticky packet" of TCP message effectively.
2. Send messages to the device:
First, when the connection is created, the connection to the TCP is preserved:
Static Final New Defaultchannelgroup ( globaleventexecutor.instance); @Override publicvoidthrows Exception { // A Closed channel would be removed from Channelgroup automatically channels.add (Ctx.channel ()); }
When you need to send a message to a device, you can traverse the Channelgroup, find the corresponding channel, and send a message to the channel:
for (Io.netty.channel.Channel c:echoserverhandler.channels) { = Unpooled.copiedbuffer ( Message.getbytes ()); C.writeandflush (msg); }
3. Heartbeat detection
The Netty server needs to know if the device is working properly and can use Netty's Idlestatehandler when a device is unable to collect data due to a power outage or other cause, and the sample code is as follows:
Ch.pipeline (). AddLast (NewIdlestatehandler (3*60,0,0) ); Ch.pipeline (). AddLast (NewHeartbeathandler ());/*** Handler implementation for heart beating.*/ Public classHeartbeathandlerextendschannelinboundhandleradapter{@Override Public voidusereventtriggered (Channelhandlercontext ctx, Object evt)throwsException {if(evtinstanceofidlestateevent) {Idlestateevent Event=(idlestateevent) evt; if(event.state () = =idlestate.reader_idle) { //Read TimeoutSystem.out.println ("Reader_idle:read timeout from" +Ctx.channel (). remoteaddress ()); //Ctx.disconnect ();//Channel Disconnect } } }}
4. RABBITMQ message receiving and sending
Nettymqserver messaging is spring AMQP and is easy to use simply by configuring it in a configuration file.
Nettymqserver Message reception can also take spring AMQP, but because the spring-related configuration is not very familiar, in order to better use MQ, the RABBITMQ Client Java API is used to implement:
Connection Connection =connnectionfactory.newconnection (); Channel Channel=Connection.createchannel (); Channel.exchangedeclare (Exchangename,"Direct",true, false,NULL); Channel.queuedeclare (QueueName,true,false,false,NULL); Channel.queuebind (QueueName, Exchangename, Routekey); //Process the message one by oneChannel.basicqos (1); Queueingconsumer Queueingconsumer=NewQueueingconsumer (channel); //Auto-ack is FalseChannel.basicconsume (QueueName,false, Queueingconsumer); while(true) {queueingconsumer.delivery Delivery=Queueingconsumer. Nextdelivery (); String message=NewString (Delivery.getbody ()); Log.debug ("Mq Receiver Get Message"); //Send the message to all connected clients//If you want to send to a specified client, just add//your own logic and ACK manually//Be Aware this channelgroup is thread safeLog.info (String.Format ("conneted Client number:%d", EchoServerHandler.channels.size ())); for(Io.netty.channel.Channel c:echoserverhandler.channels) {bytebuf msg=unpooled.copiedbuffer (message. GetBytes ()); C.writeandflush (msg); } //manually ack to MQ server, the message is consumed.Channel.basicack (Delivery.getenvelope (). Getdeliverytag (), false);
How to use RABBITMQ: http://www.cnblogs.com/luxiaoxun/p/3918054.html
Source code: Https://github.com/luxiaoxun/NettyMqServer
Reference:
http://netty.io/
Http://netty.io/4.0/api/io/netty/handler/codec/LengthFieldBasedFrameDecoder.html
Http://netty.io/4.0/api/io/netty/handler/timeout/IdleStateHandler.html
Message service based on Netty and RABBITMQ