<!--Netty--> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.0.36.Final</version> </dependency> <!--Netty END-->
application.properties
重命名爲application.yml
添加如下配置:java
n: port: 7000 url: 127.0.0.1
package club.maoyupeng.demo.sslnetty.web.socket.server; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import java.net.InetSocketAddress; /** * <b>標題: Netty 服務 </b><br /> * <pre> * </pre> * * @author 毛宇鵬 * @date 建立於 上午9:02 2018/4/25 */ @Component public class NettyServer { private static final Logger log = Logger.getLogger(NettyServer.class); private final EventLoopGroup bossGroup = new NioEventLoopGroup(); private final EventLoopGroup workerGroup = new NioEventLoopGroup(); private Channel channel; /** * 啓動服務 */ public ChannelFuture run (InetSocketAddress address) { ChannelFuture f = null; try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ServerChannelInitializer()) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); f = b.bind(address).syncUninterruptibly(); channel = f.channel(); } catch (Exception e) { log.error("Netty start error:", e); } finally { if (f != null && f.isSuccess()) { log.info("Netty server listening " + address.getHostName() + " on port " + address.getPort() + " and ready for connections..."); } else { log.error("Netty server start up Error!"); } } return f; } public void destroy() { log.info("Shutdown Netty Server..."); if(channel != null) { channel.close();} workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); log.info("Shutdown Netty Server Success!"); } }
package club.maoyupeng.demo.sslnetty.web.socket.server; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.CharsetUtil; /** * <b>標題: </b><br /> * <pre> * </pre> * * @author 毛宇鵬 * @date 建立於 上午9:13 2018/4/25 */ public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel socketChannel) { // 解碼編碼 socketChannel.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8)); socketChannel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8)); socketChannel.pipeline().addLast(new ServerHandler()); } }
package club.maoyupeng.demo.sslnetty.web.socket.server; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; /** * <b>標題: </b><br /> * <pre> * </pre> * * @author 毛宇鵬 * @date 建立於 上午9:14 2018/4/25 */ public class ServerHandler extends SimpleChannelInboundHandler<Object> { @Override public void channelRead0(ChannelHandlerContext ctx, Object msg) { System.out.println("server receive message :"+ msg); ctx.channel().writeAndFlush("yes server already accept your message" + msg); ctx.close(); } @Override public void channelActive(ChannelHandlerContext ctx) { System.out.println("channelActive>>>>>>>>"); } }
package club.maoyupeng.demo.sslnetty.web.socket.client; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.AttributeKey; import io.netty.util.CharsetUtil; import org.apache.log4j.Logger; import java.net.InetSocketAddress; /** * <b>標題: </b><br /> * <pre> * </pre> * * @author 毛宇鵬 * @date 建立於 上午10:56 2018/4/25 */ public class NettyClient { private static final Logger log = Logger.getLogger(NettyClient.class); private static Bootstrap b; private static ChannelFuture f; private static final EventLoopGroup workerGroup = new NioEventLoopGroup(); private static void init () { try { log.info("init..."); b = new Bootstrap(); b.group(workerGroup); b.channel(NioSocketChannel.class); b.option(ChannelOption.SO_KEEPALIVE, true); b.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) { // 解碼編碼 socketChannel.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8)); socketChannel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8)); socketChannel.pipeline().addLast(new ClientHandler()); } }); } catch (Exception e) { e.printStackTrace(); } } public static Object startAndWrite(InetSocketAddress address, Object send) throws InterruptedException { init(); f = b.connect(address).sync(); // 傳數據給服務端 f.channel().writeAndFlush(send); f.channel().closeFuture().sync(); return f.channel().attr(AttributeKey.valueOf("Attribute_key")).get(); } public static void main(String[] args) { InetSocketAddress address = new InetSocketAddress("127.0.0.1", 7000); String message = "hello"; try { Object result = NettyClient.startAndWrite(address, message); log.info("....result:" + result); } catch (Exception e) { log.error(e.getMessage()); } finally { f.channel().close(); workerGroup.shutdownGracefully(); log.info("Closed client!"); } } }
package club.maoyupeng.demo.sslnetty.web.socket.client; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.AttributeKey; /** * <b>標題: </b><br /> * <pre> * </pre> * * @author 毛宇鵬 * @date 建立於 上午11:25 2018/4/25 */ public class ClientHandler extends SimpleChannelInboundHandler<Object> { @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg) { channelHandlerContext.channel().attr(AttributeKey.valueOf("Attribute_key")).set(msg); channelHandlerContext.close(); } }
package club.maoyupeng.demo.sslnetty; import club.maoyupeng.demo.sslnetty.web.socket.server.NettyServer; import io.netty.channel.ChannelFuture; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.net.InetSocketAddress; /** * @author 毛宇鵬 http://www.maoyupeng.club */ @SpringBootApplication public class SslNettyApplication implements CommandLineRunner { @Value("${n.port}") private int port; @Value("${n.url}") private String url; @Autowired private NettyServer socketServer; public static void main(String[] args) { SpringApplication.run(SslNettyApplication.class, args); } @Override public void run(String... strings) { InetSocketAddress address = new InetSocketAddress(url, port); ChannelFuture future = socketServer.run(address); Runtime.getRuntime().addShutdownHook(new Thread(){ @Override public void run() { socketServer.destroy(); } }); future.channel().closeFuture().syncUninterruptibly(); } }