javanetty服务端发送数据 netty客户端发送数据_netty

今天发点人文的东西,这三张图都拍摄于拉卜楞寺。

javanetty服务端发送数据 netty客户端发送数据_java_02

javanetty服务端发送数据 netty客户端发送数据_高性能_03

                                                                                                                                        

在学习了Netty一些列的组件之后,今天我们来实战一下,写一下客户端互相聊天的功能。

 

首先我们来分析一下这个功能应该怎么实现,假设现在有三个客户端登陆,首先我们需要将这三个客户端ID与对应的连接存到一个容器里,这里我们使用线程安全的ConcurrentHashMap以Key-Value的形式来存储这对映射关系。

 

接下来我们分析一下互聊如何实现,假设A端要与B端聊天,A端发送数据包应该具有接受信息用户B的ID与聊天信息内容,服务端收到数据包后,根据数据包内接受信息用户ID从刚才的容器中找到对应的连接,然后将聊天信息写入连接,客户端B接收消息并打印到控制台,流程结束。

 

接下来我们先来实现第一个处理登陆信息的功能,首先我们先创建一个Session对象,用于存储用户信息。

 

javanetty服务端发送数据 netty客户端发送数据_io_04

 

接下来我们来抽取出一个工具类,用来操作Session对象及绑定连接,接触连接等。

 

javanetty服务端发送数据 netty客户端发送数据_javanetty服务端发送数据_05

 

我们定义一个userIdChannelMap容器用来存储Session对象及对应的连接,创建一个绑定方法bindSession用来向容器里存放映射关系,同时给该连接绑定一个叫session的Attributes标识,里面泛型限定是一个session。

 

javanetty服务端发送数据 netty客户端发送数据_javanetty服务端发送数据_06

 

有绑定就有解除绑定功能,添加一个unBindSession方法当没有登录时用来移除容器里的映射关系,创建一个getSession方法用来从连接中获取用户信息,创建一个getChannel方法用来根据用户标识,获取连接用于发送消失时。

 

javanetty服务端发送数据 netty客户端发送数据_高性能_07

 

接下来我们改造一下之前写的用于处理登陆请求的Handler。登陆时我们先随机给用户生成一个id,并返回给用户,当然真正生产时,还是需要从数据库等持久化设施中读取的,这里我们把更多的时间放在netty上,将用户信息存入Session并与当前连接绑定,用户断线后移除绑定。

 

这样在用户登录时,我们就将用户信息与当前连接绑定,并存入内存当中,以备使用。

 

接下来我们来实现向一个客户端发送消息的功能,首先我们来定义一个发送消息数据包,里面需要定义一个指向用户ID变量,和消息变量。

 

javanetty服务端发送数据 netty客户端发送数据_io_08

 

接下来我们在服务端写一个Handler来处理这个消息请求。当服务端读取到消息时,从数据包提取用户ID去容器里查找,找到后给对应的连接写入当前客户端发送来的消息即可,如果容器中无法找到对应的连接,则说明对方不在线,消息发送失败。

 

javanetty服务端发送数据 netty客户端发送数据_netty_09

 

对方客户端相对简单,只需要将接受到的消息,打印到控制台即可。

 

javanetty服务端发送数据 netty客户端发送数据_io_10

 

最后我们回到客户端稍微改造一下,写一个发送消息的功能。

 

javanetty服务端发送数据 netty客户端发送数据_高性能_07

        

首先登陆,如果已经登陆,我们可以在控制台输入消息接收方的 userId,然后输入一个空格,再输入消息的具体内容,然后,我们就可以构建一个消息数据包,发送到服务端。

 

这样我们就完成了客户端之间的互聊功能,还是挺简单的,Netty为我们提供了极大的便利。