netty(六)--开发群聊系统

需求:

在这里插入图片描述

大概流程:

  • 编写服务端
  • 编写服务端handler
  • 编写客户端
  • 编写客户端handler

服务端开发:

server:

package com.example.demo.chat;

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;
import org.apache.catalina.Pipeline;

public class chatServer {
    public  int port;
    public chatServer(int port){
        this.port=port;
    }
    public void run () throws Exception {
        EventLoopGroup workGroup= new NioEventLoopGroup();
        EventLoopGroup boosGroup=new NioEventLoopGroup();
        try{
            ServerBootstrap bootstrap=new ServerBootstrap();
            bootstrap.group(boosGroup,workGroup)
                    .channel(NioServerSocketChannel.class)//使用NioServerSocketChannel,作为服务器的通道实现
                    .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("decode", new StringDecoder());
                            //编码器
                            pipeline.addLast("encode",new StringEncoder());
                            //自定义处理
                            pipeline.addLast("myHandler",new chatServerHandler());
                        }
                    });
            ChannelFuture future=bootstrap.bind(this.port).sync();
            future.channel().closeFuture().sync();
        }finally {
            workGroup.shutdownGracefully();;
            boosGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new chatServer(6668).run();
    }
}


serverHandler:

package com.example.demo.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.text.SimpleDateFormat;
import java.util.Date;

public class chatServerHandler extends SimpleChannelInboundHandler {

    //定义一个channel组,管理所有的channel
    private static ChannelGroup channelGroup=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    private static  SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    //一旦连接就会执行的函数
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel=ctx.channel();
        channelGroup.add(channel);
        //给房间中的人发送消息
        channelGroup.writeAndFlush("客户端"+channel.remoteAddress()+"加入了聊天室,时间"+format.format(new Date()));

    }
    //断开连接触发函数

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel=ctx.channel();
        channelGroup.remove(channel);
        channelGroup.writeAndFlush("客户端"+channel.remoteAddress()+"退出了房间,时间:"+format.format(new Date()));
        System.out.println("当前人数:"+channelGroup.size());
    }

    @Override
    protected void messageReceived(ChannelHandlerContext ctx, Object o) throws Exception {
        //获取到当前的channel
        Channel channel=ctx.channel();
        //遍历group,根据不同情况回送不同的数据
        for (Channel ch : channelGroup) {
             if(channel!=ch){
                 ch.writeAndFlush("客户"+channel.remoteAddress()+"发送了一条消息:"+o);
             }else{
                 channel.writeAndFlush("我给自己发送了一条消息"+o);
             }
        }

    }

}

客户端开发:

package com.example.demo.chat;

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 client {
    private String host;
    private int port;
    public client(String host,int port){
        this.host=host;
        this.port=port;
    }
    public void run() throws Exception {
        EventLoopGroup group=new NioEventLoopGroup();
        try{
            Bootstrap bootstrap=new Bootstrap();
            bootstrap.group(group).channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>()
                    {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline=socketChannel.pipeline();
                            pipeline.addLast("decode",new  StringDecoder());
                            pipeline.addLast("encode", new StringEncoder());
                            pipeline.addLast("myHandler",new clientHandler());
                        }
                    });
            //读取数据,发送数据
            ChannelFuture future=bootstrap.connect(this.host,this.port).sync();
            Scanner scanner=new Scanner(System.in);
            Channel channel=future.channel();
            while(scanner.hasNextLine()){
                String msg=scanner.nextLine();
                channel.writeAndFlush(msg);
            }
        }finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        new client("127.0.0.1",6668).run();
    }
}

客户端handler:

public class clientHandler extends SimpleChannelInboundHandler {

    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
        System.out.println("客户接受到了一条消息----"+o);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值