package io.netty.groupchat;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
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;
public class GroupChatServer {
private int PORT;
public GroupChatServer(int port){
this.PORT=port;
}
public void run() throws InterruptedException {
//创建二个线程组
EventLoopGroup boosGroup = new NioEventLoopGroup(1);
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(boosGroup,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 {
ChannelPipeline pipeline = socketChannel.pipeline();
//加入一个解码器
pipeline.addLast("decoder",new StringDecoder());
pipeline.addLast("encoder",new StringEncoder());
pipeline.addLast("myBsiness",new GroupChatServerHandler());
}
});
System.out.println("netty start.....");
ChannelFuture channelFuture = serverBootstrap.bind(PORT).sync();
channelFuture.channel().closeFuture().sync();
}finally {
boosGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
GroupChatServer groupChatServer = new GroupChatServer(7000);
groupChatServer.run();
}
}
package io.netty.groupchat;
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.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {
//定义一个channel组 管理所有的channel
//单独聊
public static Map<String,Channel> channelMap=new HashMap<>();
/**
* GlobalEventExecutor.INSTANCE 一个单例 全局事件执行器
* 群聊
*/
private static ChannelGroup channelGroup=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
* 一旦连接创建好之后,将当前socketChannel加入到集合中
* @param ctx
* @throws Exception
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
//该方法会将channelGroup中所有的channel遍历并发送消息
channelGroup.writeAndFlush("[客户端]"+channel.remoteAddress()+"加入聊天"+sdf.format(new Date())+"\n");
channelGroup.add(channel);
//将socketchannel上线之后,给其它已经连接的客户端的给一个推送
//key 用户id value:channel
channelMap.put("100",channel);
}
/**
* 客户端连接成功
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println(ctx.channel().remoteAddress()+"上线\n");
}
//获取客户端的请求数据
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
//获取当前的channel
Channel channel = channelHandlerContext.channel();
//遍历channelGroup 根据不同的channel回送不同的东西
channelGroup.forEach((ch)->{
if(ch !=channel){
ch.writeAndFlush("客户"+channel.remoteAddress()+"发送了一个消息:"+s+"\n");
}else {
ch.writeAndFlush("自己发送了消息:"+s+"\n");
}
});
}
/**
* 客户端不被激活
* @param ctx
* @throws Exception
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println(ctx.channel().remoteAddress()+"离线\n");
}
/**
* 断开连接
* @param ctx
* @throws Exception
*/
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
channelGroup.writeAndFlush("[客户端]"+channel.remoteAddress()+"离开了\n");
System.out.println("channelGroupSize:"+channelGroup.size());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//关闭通道
ctx.close();
}
}
package io.netty.groupchat;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
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;
public class GroupChatClient {
private int prot;
private String host;
public GroupChatClient(int port,String host) {
this.prot=port;
this.host=host;
}
public GroupChatClient(String s, int i) {
this.prot=i;
this.host=s;
}
public void run() throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup(1);
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.group(group).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast("StringDecoder",new StringDecoder());
pipeline.addLast("StringEncoder",new StringEncoder());
pipeline.addLast("myHandler",new GroupChatClinetHandler());
}
});
ChannelFuture channelFuture = bootstrap.connect(host, prot).sync();
Channel channel = channelFuture.channel();
System.out.println("客户端启动好了"+channel.localAddress());
Scanner scanner=new Scanner(System.in);
while (scanner.hasNextLine()){
String value=scanner.nextLine();
//给服务单发送消息
channel.writeAndFlush(value);
}
}finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
new GroupChatClient("127.0.0.1",7000).run();
}
}
package io.netty.groupchat;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class GroupChatClinetHandler extends SimpleChannelInboundHandler<String> {
/**
* 服务端返回的信息
* @param channelHandlerContext
* @param s
* @throws Exception
*/
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
System.out.println("服务端返回信息"+s);
}
}