SpringBoot整合Netty
总体来说只需要三个步骤,下面详细介绍
第一步 创建SpringBoot工程snetty
第二步 创建子模块也就是ModuleClient
,Server
,均为SpringBoot工程
第三步 将服务器端和客户端的代码分别打成Jar包,运行Jar包。因为Netty
需要客户端与服务器端两个端口才能看到效果,但是IDE的console只有一个窗口,所以需要将两个端口代码分别打成Jar包,这样再运行的话,就有两个窗口了。
先说一下遇到的问题,具体代码在下边。
打包运行
因为我运行Jar包使用的是mvn exec:java
这个命令,是将主函数main
的参数构建在pom.xml
文件中。
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>run-server</id>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.bihang.server.server2.EchoServer</mainClass>
<arguments>
<argument>${echo-server.port}</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
也就是说当我用mvn clean package
这个命令将服务器端的代码打成Jar包之后,再运行mvn exec:java
命令,此时服务器端就启动了。
<mainClass>com.bihang.server.server2.EchoServer</mainClass>
这里放的就是主函数。
<arguments>
<argument>${echo-server.port}</argument>
</arguments>
这里放的是主函数的参数。
获取父级pom.xml的信息
${echo-server.port}
这个值是从父级pom.xml
中的properties
中获取的,很关键的就是,在子模块Server
的pom.xml中的<parent>
标签中要这么写才能获得父级pom.xml
中的信息。
<parent>
<groupId>com.bihang</groupId>
<artifactId>snetty</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- lookup parent from repository -->
</parent>
父级中的properties
:
<properties>
<java.version>1.8</java.version>
<echo-server.hostname>127.0.0.1</echo-server.hostname>
<echo-server.port>8888</echo-server.port>
</properties>
并且父级中的<packaging>
标签要改成pom
形式
<packaging>pom</packaging>
具体代码
引入依赖
<!--Netty-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.36.Final</version>
</dependency>
<!--Netty END-->
<!-- 日志文件管理包 -->
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
服务器端和客户端都只需要两部分代码,一个是处理器程序,一个是引导程序。
服务器端的EchoServerHandler
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
System.out.println(
"Server received: " + in.toString(CharsetUtil.UTF_8));
ctx.write(in);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
服务器端的EchoServer
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.net.InetSocketAddress;
public class EchoServer {
private final int port;
public EchoServer(int port) {
this.port = port;
}
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.err.println(
"Usage: " + EchoServer.class.getSimpleName() +
" <port>");
}
int port = Integer.parseInt(args[0]);
new EchoServer(port).start();
}
public void start() throws Exception {
final EchoServerHandler serverHandler = new EchoServerHandler();
EventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(serverHandler);
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
}
客户端的EchoClientHandler
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
//在到服务器的连接已经建立之后将被调用
@Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!",
CharsetUtil.UTF_8));
}
//当从服务器接收到一条消息时被调用
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf in) throws Exception {
System.out.println(
"Client received: " + in.toString(CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
客户端的EchoClient
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.net.InetSocketAddress;
public class EchoClient {
private final String host;
private final int port;
public EchoClient(String host, int port) {
this.host = host;
this.port = port;
}
public void start() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws Exception {
ch.pipeline().addLast(
new EchoClientHandler());
}
});
ChannelFuture f = b.connect().sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.err.println(
"Usage: " + EchoClient.class.getSimpleName() +
" <host> <port>");
return;
}
String host = args[0];
int port = Integer.parseInt(args[1]);
new EchoClient(host, port).start();
}
}
SpringBoot整合Netty的更多相关文章
- SpringBoot整合Netty并使用Protobuf进行数据传输(附工程)
前言 本篇文章主要介绍的是SpringBoot整合Netty以及使用Protobuf进行数据传输的相关内容.Protobuf会简单的介绍下用法,至于Netty在之前的文章中已经简单的介绍过了,这里就不 ...
- springboot整合netty(二)
目录 前言 正文 代码 1. 新建一个springboot项目,在pom文件中添加netty依赖: 2.新建netty服务 3.netty调用所需的服务类 4 springboot启动类 5.测试 我 ...
- springboot整合netty的多种方式
netty作为一个高性能的io框架,是非好用的一个技术框架, Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户. ...
- springboot整合netty,多种启动netty的方式,展现bean得多种启动方法
首先讲解下,spring中初始化加载问题: 很多时候,我们自己写的线程池,还有bean对象,还有其他的服务类,都可以通过,相关注解进行交给spring去管理,那么我们如何让nettyserver初始化 ...
- 第6章 使用springboot整合netty搭建后台
我们不会去使用自增长的id,在现阶段的互联网开发过程中,自增长的id是已经不适用了.在未来随着系统版本的迭代,用户数量的递增,肯定会做分库分表,去做一些相应的切分.在这个时候我们就需要有一个唯一的id ...
- SpringBoot整合Netty实现socket通讯简单demo
依赖 <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifa ...
- SpringBoot整合Redis使用Restful风格实现CRUD功能
前言 本篇文章主要介绍的是SpringBoot整合Redis,使用Restful风格实现的CRUD功能. Redis 介绍 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-valu ...
- SpringBoot整合Swagger和Actuator
前言 本篇文章主要介绍的是SpringBoot整合Swagger(API文档生成框架)和SpringBoot整合Actuator(项目监控)使用教程. SpringBoot整合Swagger 说明:如 ...
- SpringBoot整合Guacamole教程
前言 本文主要介绍的是SpringBoot如何整合Guacamole在浏览器是远程桌面的访问. Guacamole 介绍 Apache Guacamole 是一个无客户端远程桌面网关.它支持标准协议, ...
随机推荐
- Android------TabLayout的使用
https://www.jianshu.com/p/2b2bb6be83a8 主要放在 -------> Design库中的TabLayout的使用. margin和padding的区别 外边距 ...
- 通过Metasploit生成各种后门
生成windows后门 1.首先生成后门 [root@localhost ~]# msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ ...
- flex定位下overflow失效的问题研究
概述 这是我在写移动端页面遇到的问题及解决方法,记录下来供以后开发时参考,相信对其他人也有用. 问题 之前写移动端页面,有一个顶条是导航条,需要固定在页面顶部,并且里面的元素需要可以左右滚动. 但是当 ...
- fastjson 反序列化漏洞笔记,比较乱
现在思路还是有点乱,希望后面能重新写 先上pon.xml 包 <?xml version="1.0" encoding="UTF-8"?> < ...
- postgresql-日志表
pg_log,数据库日志表postgresqllog CREATE TABLE postgres_log ( log_time timestamp(3) with time zone, 日志生成时间 ...
- postgresql-死锁
死锁问题:1.长事务,事务中包含了文书的上传下载,导致其他表的锁等待,最终导致死锁. 2.并发更新,如果更新慢的话,很可能导致,锁等待.需要加for update或者ad lock 3.数据库中查询p ...
- POJ 2665
#include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("a ...
- vue教程3-07 vue-loader
vue-loader: vue-loader: 其他loader -> css-loader.url-loader.html-loader..... 后台: nodeJs -> requi ...
- Python全局解释器锁 -- GIL
首先强调背景: 1.GIL是什么?GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定. 2.每个CPU在同一时间只能 ...
- (转) argparse — 解析命令参数和选项
原文地址:https://pythoncaff.com/docs/pymotw/argparse-command-line-option-and-argument-parsing/166 https: ...