Netty是一个Java的NIO客户端服务端框架可以快速的开发网络应用程序,比如客户端和服务端的协议,大大简化了网络程序的开发过程。我们知道Netty的整体架构主要由3部分组成:缓冲(buffer)、通道(channel)、事件模型(event model)。所有的高级也行都构建于这三个组件之上。下面我们基于这个架构实现一个简单的网络聊天功能。
1.环境:
JDK 7
Maven3
Netty 4.1
IDEA14
2.服务端
服务端的handler
netty的所有IO处理都是基于事件驱动的,所以对于服务端我们先从服务端的Handler开始:
这里我新建了SimpleChatServerHandler类,让他继承于SimpleChannelInboundHandler。并重写父类的一些方法,源码如下:
package netty.cookbook.simplechat;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
/**
* Created by louyuting on 16/12/8.
* 服务端处理IO
*/
public class SimpleChatServerHandler extends SimpleChannelInboundHandler<String>{
public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
/**
* 每当服务端收到新的客户端连接时,客户端的channel存入ChannelGroup列表中,并通知列表中其他客户端channel
* @param ctx
* @throws Exception
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
//获取连接的channel
Channel incomming = ctx.channel();
//通知所有已经连接到服务器的客户端,有一个新的通道加入
for(Channel channel:channels){
channel.writeAndFlush("[SERVER]-"+incomming.remoteAddress()+"加入\n");
}
channels.add(ctx.channel());
}
/**
*每当服务端断开客户端连接时,客户端的channel从ChannelGroup中移除,并通知列表中其他客户端channel
* @param ctx
* @throws Exception
*/
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
//获取连接的channel
Channel incomming = ctx.channel();
for(Channel channel:channels){
channel.writeAndFlush("[SERVER]-"+incomming.remoteAddress()+"离开\n");
}
//从服务端的channelGroup中移除当前离开的客户端
channels.remove(ctx.channel());
}
/**
* 每当从服务端读到客户端写入信息时,将信息转发给其他客户端的Channel.
* @param ctx
* @param msg
* @throws Exception
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
Channel incomming = ctx.channel();
//将收到的信息转发给全部的客户端channel
for(Channel channel:channels){
if(channel != incomming) {
channel.writeAndFlush("[" + incomming.remoteAddress() + "]" + msg +