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


最近接到一個關於寫UDP服務器的任務,然后去netty官網下載了netty的jar包(netty-4.0.49.Final.tar.bz2),解壓后,可以看到上面有不少example,找到其中的關於UDP的例子。

在此學習。

直接上栗子:

 服務端:QuoteOfTheMomentServer.java(其中的代碼稍微有點修改,測試了下redis,需要的同學可以直接把jar包中的栗子拷貝下來即可)

 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.java

 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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM