netty學習:UDP服務器與Spring整合

最近接到一個關於寫UDP服務器的任務,而後去netty官網下載了netty的jar包(netty-4.0.49.Final.tar.bz2),解壓後,能夠看到上面有很多example,找到其中的關於UDP的例子。html

在此學習。java

直接上栗子:redis

 服務端:QuoteOfTheMomentServer.java(其中的代碼稍微有點修改,測試了下redis,須要的同窗能夠直接把jar包中的栗子拷貝下來便可)spring

 1 package com.wj.test;
 2 
 3 import org.slf4j.Logger;
 4 import org.slf4j.LoggerFactory;
 5 
 6 import io.netty.bootstrap.Bootstrap;
 7 import io.netty.channel.ChannelOption;
 8 import io.netty.channel.EventLoopGroup;
 9 import io.netty.channel.nio.NioEventLoopGroup;
10 import io.netty.channel.socket.nio.NioDatagramChannel;
11 
12 /**
13  * A UDP server that responds to the QOTM (quote of the moment) request to a {@link QuoteOfTheMomentClient}.
14  *
15  * Inspired by <a href="http://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html">the official
16  * Java tutorial</a>.
17  */
18 public final class QuoteOfTheMomentServer {
19 
20     private static final int PORT = Integer.parseInt(System.getProperty("port", "8889"));
21 
22     private static final Logger log=LoggerFactory.getLogger(QuoteOfTheMomentServer.class);
23     
24     public static void main(String[] args) throws Exception {
25         EventLoopGroup group = new NioEventLoopGroup();
26         log.info("QuoteOfTheMomentServer" + " + start");
27         try {
28             Bootstrap b = new Bootstrap();
29             b.group(group)
30              .channel(NioDatagramChannel.class)
31              .option(ChannelOption.SO_BROADCAST, true)
32              .handler(new QuoteOfTheMomentServerHandler());
33 
34             b.bind(PORT).sync().channel().closeFuture().await();
35         } finally {
36             group.shutdownGracefully();
37         }
38     }
39 }
 
 1 /*
 2  * Copyright 2012 The Netty Project
 3  *
 4  * The Netty Project licenses this file to you under the Apache License,
 5  * version 2.0 (the "License"); you may not use this file except in compliance
 6  * with the License. You may obtain a copy of the License at:
 7  *
 8  *   http://www.apache.org/licenses/LICENSE-2.0
 9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  */
16 package com.wj.test;
17 
18 import io.netty.buffer.Unpooled;
19 import io.netty.channel.ChannelHandlerContext;
20 import io.netty.channel.SimpleChannelInboundHandler;
21 import io.netty.channel.socket.DatagramPacket;
22 import io.netty.util.CharsetUtil;
23 import redis.clients.jedis.Jedis;
24 
25 import java.util.Random;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28 
29 import com.wj.test.redis.RedisUtil;
30 
31 
32 
33 public class QuoteOfTheMomentServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
34     
35     private static final Logger log=LoggerFactory.getLogger(QuoteOfTheMomentServerHandler.class);
36 
37     private static final Random random = new Random();
38 
39     // Quotes from Mohandas K. Gandhi:
40     private static final String[] quotes = {
41         "Where there is love there is life.",
42         "First they ignore you, then they laugh at you, then they fight you, then you win.",
43         "Be the change you want to see in the world.",
44         "The weak can never forgive. Forgiveness is the attribute of the strong.",
45     };
46 
47     private static String nextQuote() {
48         int quoteId;
49         synchronized (random) {
50             quoteId = random.nextInt(quotes.length);
51         }
52         return quotes[quoteId];
53     }
54 
55     @Override
56     public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
57         System.err.println(packet);
58         
59         
60         
61         if (packet.content().toString(CharsetUtil.UTF_8) != null ) {
62             
63             System.out.println(packet.content().toString(CharsetUtil.UTF_8));
64             System.out.println(packet.sender());
65             
66             Jedis jedisK = RedisUtil.getJedis();
67             jedisK.select(1);
68             jedisK.lpush("test:udp:msg", packet.content().toString(CharsetUtil.UTF_8));
69             
70             
71             
72             ctx.write(new DatagramPacket(
73 //                    Unpooled.copiedBuffer("QOTM: " + nextQuote(), CharsetUtil.UTF_8), packet.sender()));
74                     Unpooled.copiedBuffer("QOTM: " + "sometest", CharsetUtil.UTF_8), packet.sender()));
75         }else {
76              log.info("Exception");
77         }
78     }
79 
80     @Override
81     public void channelReadComplete(ChannelHandlerContext ctx) {
82         ctx.flush();
83     }
84 
85     @Override
86     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
87         cause.printStackTrace();
88         // We don't close the channel because we can keep serving requests.
89     }
90 }

 

客戶端:QuoteOfTheMomentClient.javaexpress

 1 /*
 2  * Copyright 2012 The Netty Project
 3  *
 4  * The Netty Project licenses this file to you under the Apache License,
 5  * version 2.0 (the "License"); you may not use this file except in compliance
 6  * with the License. You may obtain a copy of the License at:
 7  *
 8  *   http://www.apache.org/licenses/LICENSE-2.0
 9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  */
16 package com.wj.test;
17 
18 import io.netty.bootstrap.Bootstrap;
19 import io.netty.buffer.Unpooled;
20 import io.netty.channel.Channel;
21 import io.netty.channel.ChannelOption;
22 import io.netty.channel.EventLoopGroup;
23 import io.netty.channel.nio.NioEventLoopGroup;
24 import io.netty.channel.socket.DatagramPacket;
25 import io.netty.channel.socket.nio.NioDatagramChannel;
26 import io.netty.util.CharsetUtil;
27 import io.netty.util.internal.SocketUtils;
28 
29 /**
30  * A UDP broadcast client that asks for a quote of the moment (QOTM) to {@link QuoteOfTheMomentServer}.
31  *
32  * Inspired by <a href="http://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html">the official
33  * Java tutorial</a>.
34  */
35 public final class QuoteOfTheMomentClient {
36 
37     static final int PORT = Integer.parseInt(System.getProperty("port", "8889"));
38 
39     public static void main(String[] args) throws Exception {
40 
41         EventLoopGroup group = new NioEventLoopGroup();
42         try {
43             Bootstrap b = new Bootstrap();
44             b.group(group)
45              .channel(NioDatagramChannel.class)
46              .option(ChannelOption.SO_BROADCAST, true)
47              .handler(new QuoteOfTheMomentClientHandler());
48 
49             Channel ch = b.bind(0).sync().channel();
50 
51             // Broadcast the QOTM request to port 8080.
52             String str = "38567071 13801783144 18917565379 20170621183115 20170621183118 05";
53             ch.writeAndFlush(new DatagramPacket(
54                     Unpooled.copiedBuffer(str, CharsetUtil.UTF_8),
55                     SocketUtils.socketAddress("localhost", PORT))).sync();
56 
57             // QuoteOfTheMomentClientHandler will close the DatagramChannel when a
58             // response is received.  If the channel is not closed within 5 seconds,
59             // print an error message and quit.
60             if (!ch.closeFuture().await(5000)) {
61                 System.err.println("QOTM request timed out.");
62             }
63         } finally {
64             group.shutdownGracefully();
65         }
66     }
67 }

 

 1 package com.wj.test;
 2 
 3 /*
 4  * Copyright 2012 The Netty Project
 5  *
 6  * The Netty Project licenses this file to you under the Apache License,
 7  * version 2.0 (the "License"); you may not use this file except in compliance
 8  * with the License. You may obtain a copy of the License at:
 9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations
16  * under the License.
17  */
18 
19 import io.netty.channel.ChannelHandlerContext;
20 import io.netty.channel.SimpleChannelInboundHandler;
21 import io.netty.channel.socket.DatagramPacket;
22 import io.netty.util.CharsetUtil;
23 
24 public class QuoteOfTheMomentClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {
25 
26     @Override
27     public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
28         String response = msg.content().toString(CharsetUtil.UTF_8);
29         if (response.startsWith("QOTM: ")) {
30             System.out.println("++++Quote of the Moment: " + response.substring(6));
31             ctx.close();
32         }
33     }
34 
35     @Override
36     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
37         cause.printStackTrace();
38         ctx.close();
39     }
40 }

 

該官方的栗子確實能夠很好的實現UDP服務器的功能,甚至你能夠寫個jedis,與redis連接起來,可是每每項目開發中簡單的結合是遠遠不夠的。好比咱們要將次UDP服務器與spring框架或者是spring boot框架結合起來,並使用RedisTemplate的操做類訪問Redis或者使用JPA連接MySQL的時候,那麼該server就要更改了,下一篇文章將會講解此UDP服務器如何與spring boot框架整合起來,並使用RedisTemplate的操做類訪問Redis。apache

相關文章
相關標籤/搜索