Vert.x(vertx) 实现TCP服务

对于Java开发人员,想要实现一个http服务,非常简单,写个servlet,打成war包,放到tomcat下就能运行。但如果要实现一个tcp服务就没那么简单了,因为tcp是传输层协议,并不像http那样,有类似tomcat的中间件给我们封装底层的网络协议,封装线程的交互。要实现一个tcp服务,只能自己动手处理网络和线程问题,这是非常考验编程功底的事情,而且如果团队人员素质不高,项目周期要求较短的情况下,是很难开发一个稳定的tcp服务的。

http报文格式

TCP协议的应用场景

很多朋友可能会有疑惑,http协议挺好用的啊,为什么要用tcp服务?要知道,http是在tcp协议的基础上封装的应用层协议。这也就意味着http协议的性能一定是比tcp要低的多的(从上图可以看到,除了请求数据外有大量的头信息等)。另外http协议自身的特性,http是一个半双工且无状态的协议,因此很多的场景http协议是无法满足的。举一个最简单的例子,我们都用过打车软件,我们发个打车的请求,很多的司机端都能够快速的接收到。如果使用http协议是实现不了的(当然可以使用websocket,这里不具体讨论),即使是通过类似于ajax轮询的手段实现,性能也都会非常低,并且实时性不好,对服务器压力大等问题,这个时候tcp协议就出场了。

再考虑另外一个场景,考驾照的时候,教练车上都有一个打卡的机器(暂且称为终端机),那么打卡的机器需要和远程的服务器连接,实时传输学员练车的动态数据,如果使用http协议,不仅仅对于终端机编程(一般采用C语言,http是在tcp之上封装的协议,所以如果使用http协议会比较繁琐)要求较高,而且http协议会有很多无用的数据(http是一种通用的协议,为了实现通用,因此http头信息有很多是不用的,且http协议是一个纯文本的协议,相比较采用二进制协议,报文会比较大),浪费带宽。所以一般类似于嵌入式设备和应用服务数据交互也都会使用tcp协议。

有朋友可能会提到使用netty也可以实现tcp服务啊,当然,netty相比较使用传统的bio或者使用原生nio都要简单的多,而且解决了粘包拆包的问题,也封装了线程模型。确实,使用netty开发tcp服务器是目前很多企业的选择,但netty入门也相对比较复杂,学习成本较高。这里给大家推荐一个异步框架,Vertx,它的底层是基于netty的,使用Vertx开发tcp服务,非常的简单。

Vertx的TCP服务端开发

vertx开发tcp服务非常的简单,整体可以分为以下几个步骤

  1. 导入vertx-core的依赖
  2. 创建tcp服务(NetServer)
  3. 监听指定端口的请求
  4. 处理请求,并响应

下面简单贴下代码,完整代码可以见GitHub,地址为:https://github.com/happy-fly/vertx

1. 在maven中引入依赖(写博客的时候,最新版本为3.6.0,写测试案例的时候最新版是3.5.4):

<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-core</artifactId>
 <version>3.6.0</version>
</dependency>

2.核心代码

// 创建TCP服务器
NetServer server = vertx.createNetServer();

// 处理连接请求
server.connectHandler(socket -> {

	socket.handler(buffer -> {
		// 在这里应该解析报文,封装为协议对象,并找到响应的处理类,得到处理结果,并响应
		System.out.println("接收到的数据为:" + buffer.toString());
		
		// 按照协议响应给客户端
		socket.write(Buffer.buffer("Server Received"));
	});

	// 监听客户端的退出连接
	socket.closeHandler(close -> {
		System.out.println("客户端退出连接");
	});

});

// 监听端口
server.listen(5555, res -> {
	if (res.succeeded()) {
		System.out.println("服务器启动成功");
	}
});

这里的逻辑非常简单,就是输出接收到客户端请求的数据,然后告诉客户端,Server Received。

下面是客户端核心代码:

// 创建一个TCP客户端
NetClient client = vertx.createNetClient();

// 连接服务器
client.connect(5555, "localhost", conn -> {
	if (conn.succeeded()) {
		NetSocket s = conn.result();
		// 向服务器写数据
		s.write(Buffer.buffer("hello"));
		
		// 读取服务器的响应数据
		s.handler(buffer -> {
			System.out.println(buffer.toString());
		});
	} else {
		System.out.println("连接服务器异常");
	}
});

客户端的实现也很简单,向服务端发送消息:hello,等待服务端的响应。

这里实现的比较简单,真实业务场景远比此要复杂的多,根据应用场景我们一般需要定义自己的协议,服务端在接收到客户端请求的时候需要根据自己定义的协议进行拆包,并封装为请求对象,然后调用具体的代码进行业务逻辑处理,待处理完毕需要将处理器处理的结果进行封包,发送给客户端。对于客户端的实现也是同样,接收到服务端的请求之后,根据协议进行拆包,处理完毕再把响应消息封包之后发给服务器。

关于Vertx创建tcp服务就完成了,是不是比起来使用bio,nio,netty都要简单的多。

Vert.x系列文章:

(一)Vert.x 简明介绍 https://blog.csdn.net/king_kgh/article/details/80772657

(二)Vert.x创建简单的HTTP服务 https://blog.csdn.net/king_kgh/article/details/80804078

(三)Vert.x Web开发之路由 https://blog.csdn.net/king_kgh/article/details/80848571

(四)Vert.x TCP服务实现 https://blog.csdn.net/king_kgh/article/details/84870775

(五)Vert.x数据库访问 Vert.x(vertx) 连接MySQL、Oracle数据库_vertx mybatis_jhappyfly的博客-CSDN博客

(六)Vert.x认证和授权 Vert.x(vertx) 认证和授权详解(包含认证和授权在Web系统中的使用)_vertx auth_jhappyfly的博客-CSDN博客

(七)Vert.x事件总线(Event Bus)与远程服务调用 Vert.x(vertx) 事件总线(EventBus)与 远程服务调用_vertx.eventbus_jhappyfly的博客-CSDN博客

Vert.x 案例代码:https://github.com/happy-fly
 

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值