您好,登錄后才能下訂單哦!
這篇文章主要講解了“Netty功能怎么實現(xiàn)”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Netty功能怎么實現(xiàn)”吧!
Netty是年初最先學(xué)習(xí)的框架,近期的圖書租借系統(tǒng)想要用上聊天功能,實現(xiàn)一對一對話聊天,在用戶登錄服務(wù)端時,獲取用戶ip與id綁定,放入channelgroup,每次循環(huán)遍歷這個ip對應(yīng)的channel,否則返回false,在用戶狀態(tài)取到是否在線,在線狀態(tài)屬于handler消息功能。
1.一對一聊天
2.展示在線人數(shù)
3.登錄驗證
4.輸入框優(yōu)化
5.可支持表情
開源萬歲
當(dāng)尋找Netty一對一聊天功能實現(xiàn)的時候,除了重溫下功能點,還能發(fā)現(xiàn)新的東西,一個小小的demo,別人卻不是這么做的,細(xì)化到驗證,還考慮到性能,看下實現(xiàn)效果頁面
需要昵稱輸入,登錄后不是簡單的數(shù)據(jù)新增
private static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true); private static ConcurrentMap<Channel, UserInfo> userInfos = new ConcurrentHashMap<>(); private static AtomicInteger userCount = new AtomicInteger(0);
讀寫鎖;
并發(fā)包;
原子計數(shù);
因為最終實現(xiàn)用戶的在線人數(shù)統(tǒng)計,用了原子類的AtomicInteger
private static AtomicInteger uidGener = new AtomicInteger(1000);
private boolean isAuth = false; // 是否認(rèn)證
private long time = 0; // 登錄時間
private int userId; // UID
private String nick; // 昵稱
private String addr; // 地址
private Channel channel;// 通道
登錄用戶信息,確定昵稱,獲取ip,每一個用戶ip,channel一一對應(yīng)放入channelGroup。
如何發(fā)送消息?
在消息處理Handler中,重寫channelread0方法
1.獲取是否存在此用戶信息的channel
2.存在將用戶id,昵稱,接收到的消息廣播到頁面顯示
3.消息不為null,讀寫鎖加鎖,找到當(dāng)前用戶的channel
4.遍歷用戶信息,通過netty寫入回調(diào)返回
if (msg instanceof FullHttpRequest) { handleHttpRequest(ctx, (FullHttpRequest) msg); } else if (msg instanceof WebSocketFrame) { handleWebSocket(ctx, (WebSocketFrame) msg); }
將Handler接受接入到Server
1.定時關(guān)閉失效的channel
2.定時向客戶端ping消息
Netty的消息處理流程
定義好父子線程組–>在childInitializer定義好相關(guān)處理通道處理器-->自己提供處理器在回調(diào)
現(xiàn)在開始回調(diào)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
將group放入消息管道
ch.pipeline().addLast(defLoopGroup,
//請求解碼器
new HttpServerCodec(),
//將多個消息轉(zhuǎn)換成單一的消息對象
new HttpObjectAggregator(65536),
//支持異步發(fā)送大的碼流,一般用于發(fā)送文件流
new ChunkedWriteHandler(),
//檢測鏈路是否讀空閑
new IdleStateHandler(60, 0, 0),
//處理握手和認(rèn)證
new UserAuthHandler(),
//處理消息的發(fā)送
new MessageHandler()
);
}
});
定時處理失效消息
// 定時掃描所有的Channel,關(guān)閉失效的Channel
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
logger.info("scanNotActiveChannel --------");
UserInfoManager.scanNotActiveChannel();
}
}, 3, 60, TimeUnit.SECONDS);
// 定時向所有客戶端發(fā)送Ping消息
executorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
UserInfoManager.broadCastPing();
}
}, 3, 50, TimeUnit.SECONDS);
前端頁面沒有什么變化。
1.綁定websocket
2.websocket調(diào)用onmessage處理消息
window.socket = new WebSocket("ws://localhost:9688/websocket")
處理技術(shù):
1.線程池
2.Lambad表達(dá)式
3.讀寫鎖提高性能
4.原子引用保證原子性,線程安全
debug
用戶登錄,判斷是否是給定的消息類型
獲取昵稱,用戶信息,code碼
==success,保存用戶信息
第一次登陸沒有此用戶id與channel,不廣播消息
用戶計數(shù)0 broadCastPing userCount: 0
當(dāng)發(fā)送消息到頁面時
觸發(fā)定時消息廣播,遍歷size
處理消息ctx.fireChannelRead(frame.retain());
此時廣播用戶計數(shù)broadCastPing userCount: 1
websocket實現(xiàn)了真正意義上的客戶端與服務(wù)器端的長連接,節(jié)省帶寬,而關(guān)注內(nèi)容本身
websocket:1--:雙向數(shù)據(jù)傳遞;
2--:基于Http
3--:非瀏覽器場合
感謝各位的閱讀,以上就是“Netty功能怎么實現(xiàn)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Netty功能怎么實現(xiàn)這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。