• 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。

  • 相关阅读:
    乐乎环球WiFi
    Freeswitch 添加可转码的G729编码
    freeswitch 使用mysql替换默认的sqlite
    IDEA项目突然提示找不到符号或程序包不存在
    JAVA_四大代码块_普通代码块、构造代码块、静态代码块、同步代码块。
    动态规划_连续子数组的最大和
    电话号码分身
    ajax中用jsonp接收json数据
    用Navicat建表的字段编码问题
    阿里云ubuntu安装jdk8+mysql+tomcat
  • 原文地址:https://www.cnblogs.com/wj0816/p/7451918.html
Copyright © 2020-2023  润新知