zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    JVM Ecosystem Report 2020
    TiDB 简介
    Docker镜像分层打包方案
    Promethues + Grafana + AlertManager使用总结
    Spring Boot自动注入原理
    Spring Boot 2.x 自定义Endpoint
    Oracle 等待事件 Enq: CF
    1000行MySQL学习笔记
    PostgreSQL DBA常用SQL查询语句
    MongoDB DBA常用的NoSQL语句
  • 原文地址:https://www.cnblogs.com/wj0816/p/7451918.html
Copyright © 2011-2022 走看看