用netty做文字聊天室

前言

以前一直对通讯这块不是很了解 最新学习了一下netty 搞了个简易的聊天室

为自己7秒的记忆 留下火种



准备

<!-- netty包 -->
	<dependency>
	    <groupId>io.netty</groupId>
	    <artifactId>netty-all</artifactId>
	    <version>4.1.26.Final</version>
	</dependency>


服务端代码

    1.服务器启动主方法

package netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import netty.server.init.NettyServerIniter;

/**
 * @author zth
 *
 */
public class NettyServer {
	//netty服务端监听的端口
	private static int NETTY_SERVER_PORT=9999;
	
	public static void main(String[] args) {
		EventLoopGroup group = null;
		try {
			//创建服务端
			ServerBootstrap server = new ServerBootstrap();
			//使用nio方式
			group = new NioEventLoopGroup();
			server.group(group);
			//类似serversocket吧?
			server.channel(NioServerSocketChannel.class);
			//初始化处理器
			server.childHandler(new NettyServerIniter());
			//绑定端口
			ChannelFuture channelFuture = server.bind(NETTY_SERVER_PORT).sync();
			System.out.println("netty 服务端 启动成功");
			channelFuture.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			//关闭回收线程
			group.shutdownGracefully();
		}
	
	}
}



2.频道初始化

package netty.server.init;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import netty.server.handle.NettyServerHandler;

/**
 * @author zth
 *
 */
public class NettyServerIniter extends ChannelInitializer<SocketChannel>{

	@Override
	protected void initChannel(SocketChannel channel) throws Exception {
		ChannelPipeline pipeline = channel.pipeline();
		//采用分隔符解码器
		pipeline.addLast("framer",new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
		//字符串解码
		pipeline.addLast("decoder",new StringDecoder());
		//字符创编码
		pipeline.addLast("encoder",new StringEncoder());
		//自定义处理器
		pipeline.addLast("handler",new NettyServerHandler());
	}

}



3.自定义处理器

package netty.server.handle;


import java.net.InetAddress;
import java.util.Date;


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;


/**
 * @author zth
 *
 */
public class NettyServerHandler extends SimpleChannelInboundHandler<String>{
	//频道组 用来加入客户端频道进行广播
	private static final ChannelGroup CHANNEL_GROUP = new DefaultChannelGroup("ChannelGroups", GlobalEventExecutor.INSTANCE);
	//退出编码
	private static String exit_code = "exit";
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
		System.out.println("服务端接收消息:"+msg);
		if(exit_code.equals(msg)) {
			System.out.println("关闭服务端");
			ctx.close();
		}
		Date date = new Date();
		String returnMsg = date.toLocaleString()+":"+msg+"\n";
		//单体回复消息客户端
//		ctx.writeAndFlush("回复:"+returnMsg);
		//广播所有客户端
		Channel ch = ctx.channel();
		CHANNEL_GROUP.add(ch);
		CHANNEL_GROUP.writeAndFlush("广播:"+returnMsg);
	}


	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("连接客户端:"+ctx.channel().remoteAddress());
		String returnStr = "客户端 成功 与服务端"+InetAddress.getLocalHost().getHostName()+"建立连接\n";
		ctx.writeAndFlush(returnStr);
		super.channelActive(ctx);
	}
	
}




客户端代码

1.客户端主程序

package netty.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import netty.client.handler.NettyClientHandler;

/**
 * @author zth
 *
 */
public class NettyClient2 {
	//服务端地址
	private static String netty_server_host = "127.0.0.1";
	//服务端端口
	private static int netty_server_port = 9999;
	
	public static void main(String[] args) throws InterruptedException, IOException {
		//netty客户端
		Bootstrap client = new Bootstrap();
		//采用nio
		EventLoopGroup group = new NioEventLoopGroup();
		client.group(group);
		client.channel(NioSocketChannel.class);
		//处理器设置
		client.handler(new ChannelInitializer<SocketChannel>() {
			//初始化处理器设置
			@Override
			protected void initChannel(SocketChannel ch) throws Exception {
				ChannelPipeline pie = ch.pipeline();
				pie.addLast("framer",new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
				pie.addLast("decoder",new StringDecoder());
				pie.addLast("encoder",new StringEncoder());
				//自定义处理器
				pie.addLast(new NettyClientHandler());
			}
		});
		//连接服务端
		Channel channel = client.connect(netty_server_host, netty_server_port).sync().channel();
		//加入消息
		String startMsg = "client2加入了聊天\n";
		channel.writeAndFlush(startMsg);
		//模拟聊天……
		while (true) {
			System.out.println("请输入想要发送的消息:");
			InputStreamReader in = new InputStreamReader(System.in);
			BufferedReader reader = new BufferedReader(in);
			String msg = reader.readLine()+"\r\n";
//			System.out.println("客户端发送消息:"+msg);
			channel.writeAndFlush(msg);
		}
	}
}


2.自定义处理器

package netty.client.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * @author zth
 *
 */
public class NettyClientHandler extends SimpleChannelInboundHandler<String>{

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
		System.out.println("22222接收到服务端消息:"+msg);
	}

}


完成 可以多复制几个客户端 开启来 通过广播把消息传给每一个客户端

还有很多功能没做 比如传图片,聊天记录,表情包什么的

可以通过文件服务器oss 数据什么的来完成

猜你喜欢

转载自blog.csdn.net/zth0825/article/details/81065902