從入門(mén)到超神進(jìn)階的Netty群聊系統(tǒng)
服務(wù)端
服務(wù)端一樣的需要?jiǎng)?chuàng)建BossGroup 和 WorkGroup , 然后使用ServerBootStrap 來(lái)配置Netty和啟動(dòng)Netty。
public class NettyGroupChatServer {
public static void main(String[] args) {
new NettyGroupChatServer().start();
}
//監(jiān)聽(tīng)
public void start(){
//循環(huán)組
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workGroup = new NioEventLoopGroup();
//啟動(dòng)引導(dǎo)
ServerBootstrap bootstrap = new ServerBootstrap();
//Netty配置
bootstrap.group(bossGroup,workGroup)
.option(ChannelOption.SO_BACKLOG,32)
.childOption(ChannelOption.SO_KEEPALIVE,true)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
//解碼器
channel.pipeline().addLast("decoder", new StringDecoder());
//編碼器
channel.pipeline().addLast("encoder",new StringEncoder());
//處理器
channel.pipeline().addLast("nettyGroupChatHandler",new NettyGroupChatServerHandler());
}
});
try {
//啟動(dòng)服務(wù)
ChannelFuture future = bootstrap.bind(new InetSocketAddress("127.0.0.1", 8888)).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//關(guān)閉資源
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
服務(wù)端處理器我們通過(guò)繼承 SimpleChannelInboundHandler 入站Handler來(lái)處理消息。
其中提供了幾個(gè)方法
- channelRead0 ():讀取消息
- handlerRemoved ():客戶端斷開(kāi)
- handlerAdded ():客戶端建立連接
- exceptionCaught ():出現(xiàn)異常
具體代碼如下
public class NettyGroupChatServerHandler extends SimpleChannelInboundHandler<String> {
//把所有客戶端的channel保存起來(lái)
private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
String message = dateFormat.format(new Date())+":%s:"+msg;
//消息轉(zhuǎn)發(fā)給所有的客戶端
channels.forEach(channel -> {
if(channel == ctx.channel()){
String sendMsg = String.format(message, "我");
channel.writeAndFlush(sendMsg);
System.out.println(sendMsg);
}else{
String sendMsg = String.format(message, ctx.channel().remoteAddress());
channel.writeAndFlush(sendMsg);
System.out.println(sendMsg);
}
});
}
//斷開(kāi)連接 , 把消息廣播給其他客戶端
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
String message = dateFormat.format(new Date())+":"+ctx.channel().remoteAddress()+":斷開(kāi)連接";
channels.writeAndFlush(message);
System.out.println(message);
}
//建立連接
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
String message = dateFormat.format(new Date())+":"+ctx.channel().remoteAddress()+":加入聊天室";
//自動(dòng)把消息廣播給其客戶端
channels.writeAndFlush(message);
//客戶端加入組
channels.add(ctx.channel());
System.out.println(message);
}
//出現(xiàn)異常
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.channel().close();
}
//客戶端退出
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
String message = dateFormat.format(new Date())+":"+ctx.channel().remoteAddress()+":退出聊天室";
System.out.println(message);
}
//客戶端出于活動(dòng)
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String message = dateFormat.format(new Date())+":"+ctx.channel().remoteAddress()+":上線啦";
System.out.println(message);
}
}
客戶端
客戶端需要?jiǎng)?chuàng)建一個(gè)循環(huán)事件組,然后通過(guò)BootStrap去啟動(dòng),然后掃描鍵盤(pán)輸入作為數(shù)據(jù)源來(lái)把信息發(fā)送給服務(wù)端
public class NettyGroupChatClient {
public static void main(String[] args) {
new NettyGroupChatClient().start();
}
public void start(){
NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
//解碼器
channel.pipeline().addLast("decoder", new StringDecoder());
//編碼器
channel.pipeline().addLast("encoder",new StringEncoder());
//處理器
channel.pipeline().addLast("nettyGroupChatClientHandler",new NettyGroupChatClientHandler());
}
});
try {
ChannelFuture future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 8888)).sync();
//通道
Channel channel = future.channel();
//掃描鍵盤(pán)輸入
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextLine()){
String message = scanner.nextLine();
//發(fā)送數(shù)據(jù)
channel.writeAndFlush(message);
}
} catch (InterruptedException e) {
}finally {
eventLoopGroup.shutdownGracefully();
}
}
}
對(duì)于處理器只需要接收服務(wù)端轉(zhuǎn)發(fā)過(guò)來(lái)的消息即可
public class NettyGroupChatClientHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println(msg);
}
}
啟動(dòng)服務(wù)端和多個(gè)客戶端,效果如下



到此這篇關(guān)于從入門(mén)到超神系列的Netty群聊系統(tǒng)的文章就介紹到這了,更多相關(guān)Netty群聊系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用 IntelliJ IDEA 編寫(xiě) Spark 應(yīng)用程序(Sc
本教程展示了如何在IntelliJIDEA中使用Maven編寫(xiě)和運(yùn)行一個(gè)簡(jiǎn)單的Spark應(yīng)用程序(例如WordCount程序),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-11-11
SpringBoot實(shí)現(xiàn)異步事件Event詳解
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)異步事件Event詳解,異步事件的模式,通常將一些非主要的業(yè)務(wù)放在監(jiān)聽(tīng)器中執(zhí)行,因?yàn)楸O(jiān)聽(tīng)器中存在失敗的風(fēng)險(xiǎn),所以使用的時(shí)候需要注意,需要的朋友可以參考下2023-11-11
Mybatis傳遞多個(gè)參數(shù)的三種實(shí)現(xiàn)方法
這篇文章主要介紹了Mybatis傳遞多個(gè)參數(shù)的三種實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Intellij IDEA 最全超實(shí)用快捷鍵整理(長(zhǎng)期更新)
這篇文章主要介紹了Intellij IDEA 最全實(shí)用快捷鍵整理(長(zhǎng)期更新),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
SpringBoot 集成 Nebula的操作過(guò)程
這篇文章主要介紹了SpringBoot 集成 Nebula的操作過(guò)程,通過(guò)示例代碼介紹了java 環(huán)境下如何對(duì) Nebula Graph 進(jìn)行操作,感興趣的朋友跟隨小編一起看看吧2024-05-05
idea tomcat亂碼問(wèn)題的解決及相關(guān)設(shè)置的步驟
這篇文章主要介紹了idea tomcat亂碼問(wèn)題的解決及相關(guān)設(shè)置的步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11

