package com.chigo.it.netty.chat;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
/**
* @description:
* @version: 1.0
*/
public class GroupChatServer implements Runnable{
public static void main(String[] args) {
new GroupChatServer().run();
}
@Override
public void run() {
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap().group(bossGroup, workGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("decoder", new StringDecoder());
socketChannel.pipeline().addLast("encoder", new StringEncoder());
socketChannel.pipeline().addLast("serverHandler",new GroupChatServerHandler());
}
});
System.out.println("服务器启动了....");
ChannelFuture channelFuture = serverBootstrap.bind(9999).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
package com.chigo.it.netty.chat;
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;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @description:
* @version: 1.0
*/
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {
//全局事件执行器
private static final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd:hh:mm:ss"));
//连接建立,第一个搪行
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd:hh:mm:ss"));
Channel channel = ctx.channel();
channelGroup.writeAndFlush("[客户端]" + channel.remoteAddress() + " " + format + " 加入聊天");
channelGroup.add(channel);
}
//读取信息
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
channelGroup.forEach(channel -> {
if (channel != channelHandlerContext.channel()) {
channel.writeAndFlush("[客户端]" + channelHandlerContext.channel().remoteAddress() + " " + format + "发送了消息=>" + s + "\n");
} else {
channel.writeAndFlush("[自己]发送了消息=>" + s);
}
});
}
//channel处于活动状态,提示上线
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//channelGroup.writeAndFlush("[客户端]" + ctx.channel().remoteAddress() + " " + format + "=>上线了");
System.out.println("[客户端]" + ctx.channel().remoteAddress() + " " + format + "=>上线了");
}
//channel处于不活动状态,提示离线了
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//channelGroup.writeAndFlush("[客户端]" + ctx.channel().remoteAddress() + " " + format + "=>离线了");
System.out.println("[客户端]" + ctx.channel().remoteAddress() + " " + format + "=>离线了");
}
//断开连接,将客户离开信息推送给当前在线的客户
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
channelGroup.writeAndFlush("[客户端]" + channel.remoteAddress() + " " + format + "=>离开了");
System.out.println("channelGroup size :" + channelGroup.size());
channelGroup.remove(channel);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.channel().close();
}
}
package com.chigo.it.netty.chat;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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 java.util.Scanner;
/**
* @description:
* @version: 1.0
*/
public class GroupChatClient implements Runnable{
public static void main(String[] args) {
new GroupChatClient().run();
}
@Override
public void run() {
NioEventLoopGroup workGroup = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap().group(workGroup).channel(NioSocketChannel.class).option(ChannelOption.SO_KEEPALIVE, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("decoder", new StringDecoder());
socketChannel.pipeline().addLast("encoder", new StringEncoder());
socketChannel.pipeline().addLast("clientHandler",new GroupChatClientHandler());
}
});
ChannelFuture channelFuture = bootstrap.connect("localhost", 9999).sync();
System.out.println(channelFuture.channel().remoteAddress()+":客户端准备好了...");
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String message = scanner.nextLine();
channelFuture.channel().writeAndFlush(message);
}
//channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
workGroup.shutdownGracefully();
}
}
}
package com.chigo.it.netty.chat;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
* @description:
* @version: 1.0
*/
public class GroupChatClientHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
System.out.println(s.trim());
}
}