服務端
服務端一樣的需要創建bossgroup 和 workgroup , 然后使用serverbootstrap 來配置netty和啟動netty。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public class nettygroupchatserver { public static void main(string[] args) { new nettygroupchatserver().start(); } //監聽 public void start(){ //循環組 nioeventloopgroup bossgroup = new nioeventloopgroup(); nioeventloopgroup workgroup = new nioeventloopgroup(); //啟動引導 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 { //啟動服務 channelfuture future = bootstrap.bind( new inetsocketaddress( "127.0.0.1" , 8888 )).sync(); future.channel().closefuture().sync(); } catch (interruptedexception e) { e.printstacktrace(); } finally { //關閉資源 bossgroup.shutdowngracefully(); workgroup.shutdowngracefully(); } } } |
服務端處理器我們通過繼承 simplechannelinboundhandler 入站handler來處理消息。
其中提供了幾個方法
- channelread0 ():讀取消息
- handlerremoved ():客戶端斷開
- handleradded ():客戶端建立連接
- exceptioncaught ():出現異常
具體代碼如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
public class nettygroupchatserverhandler extends simplechannelinboundhandler<string> { //把所有客戶端的channel保存起來 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; //消息轉發給所有的客戶端 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); } }); } //斷開連接 , 把消息廣播給其他客戶端 @override public void handlerremoved(channelhandlercontext ctx) throws exception { string message = dateformat.format( new date())+ ":" +ctx.channel().remoteaddress()+ ":斷開連接" ; channels.writeandflush(message); system.out.println(message); } //建立連接 @override public void handleradded(channelhandlercontext ctx) throws exception { string message = dateformat.format( new date())+ ":" +ctx.channel().remoteaddress()+ ":加入聊天室" ; //自動把消息廣播給其客戶端 channels.writeandflush(message); //客戶端加入組 channels.add(ctx.channel()); system.out.println(message); } //出現異常 @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); } //客戶端出于活動 @override public void channelactive(channelhandlercontext ctx) throws exception { string message = dateformat.format( new date())+ ":" +ctx.channel().remoteaddress()+ ":上線啦" ; system.out.println(message); } } |
客戶端
客戶端需要創建一個循環事件組,然后通過bootstrap去啟動,然后掃描鍵盤輸入作為數據源來把信息發送給服務端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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(); //掃描鍵盤輸入 scanner scanner = new scanner(system.in); while (scanner.hasnextline()){ string message = scanner.nextline(); //發送數據 channel.writeandflush(message); } } catch (interruptedexception e) { } finally { eventloopgroup.shutdowngracefully(); } } } |
對于處理器只需要接收服務端轉發過來的消息即可
1
2
3
4
5
6
|
public class nettygroupchatclienthandler extends simplechannelinboundhandler<string> { @override protected void channelread0(channelhandlercontext ctx, string msg) throws exception { system.out.println(msg); } } |
啟動服務端和多個客戶端,效果如下
到此這篇關于從入門到超神系列的netty群聊系統的文章就介紹到這了,更多相關netty群聊系統內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/u014494148/article/details/119721394