Netty入门到超神系列-基于WebSocket开发聊天室

简介: 在很多的网站中都嵌入有聊天功能,最理想的方式就是使用WebSocket来开发,屏幕面前的你如果不清楚WebSocket的作用可以自己去百度一下,Netty提供了WebSocket支持,这篇文章将使用Netty作为服务器,使用WebSocket开发一个简易的聊天室系统。

在很多的网站中都嵌入有聊天功能,最理想的方式就是使用WebSocket来开发,屏幕面前的你如果不清楚WebSocket的作用可以自己去百度一下,Netty提供了WebSocket支持,这篇文章将使用Netty作为服务器,使用WebSocket开发一个简易的聊天室系统。

服务端

导入依赖

<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.42.Final</version></dependency></dependencies>

Netty提供了 WebSocketServerProtocolHandler ,它能够把平台的Http协议升级为WebSocket的WS协议,服务端代码如下

publicclassNettySocketServer {
publicstaticvoidmain(String[] args) {
NioEventLoopGroupbossGroup=newNioEventLoopGroup();
NioEventLoopGroupworkGroup=newNioEventLoopGroup();
ServerBootstrapbootstrap=newServerBootstrap();
try {
bootstrap.group(bossGroup, workGroup);
bootstrap.channel(NioServerSocketChannel.class);
bootstrap.childHandler(newChannelInitializer<SocketChannel>() {
protectedvoidinitChannel(SocketChannelchannel) throwsException {
ChannelPipelinepipeline=channel.pipeline();
//设置http编码器pipeline.addLast(newHttpServerCodec());
//支持以块的方式写数据,添加块处理器pipeline.addLast(newChunkedWriteHandler());
//http请求是分段的,通过该处理器聚合分段pipeline.addLast(newHttpObjectAggregator(8192));
//支持websocket长连接,添加SocketServer处理器,把http升级为ws协议//客户端请求方式为:ws://localhost:8000/hellopipeline.addLast(newWebSocketServerProtocolHandler("/hello"));
//处理请求,执行业务的Hnadlerpipeline.addLast(newMyWebSorcketServerHandler());
                }
            });
//启动服务器ChannelFuturesync=bootstrap.bind(8000).sync();
sync.channel().closeFuture().sync();
        }catch (Exceptione){
e.printStackTrace();
        }finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
        }
    }
}
  • 因为使用http,所以需要通过pipeline添加http编码器 HttpServerCodec
  • WebSocketServerProtocolHandler : WebSocket支持,把http升级为ws协议
  • MyWebSorcketServerHandler :该处理器是服务器处理请求的处理器

编写请求处理器

//消息进站处理 ,TextWebSocketFrame:WebSokcet消息是以“帧 Frame”的方式参数,该类是针对Text的数据publicclassMyWebSorcketServerHandlerextendsSimpleChannelInboundHandler<TextWebSocketFrame> {
//保存所有客户端privatestaticChannelGroupchannels=newDefaultChannelGroup(GlobalEventExecutor.INSTANCE);
privateSimpleDateFormatdateFormat=newSimpleDateFormat("mm:ss");
//读取消息protectedvoidchannelRead0(ChannelHandlerContextctx, TextWebSocketFramemsg) throwsException {
Stringmessage=dateFormat.format(newDate())+":%s:"+msg.text();
System.out.println("收到消息: "+ctx.channel().remoteAddress()+":"+message);
StringsendMsg=String.format(message, ctx.channel().remoteAddress());
//把消息广播给所有的客户端channels.writeAndFlush(newTextWebSocketFrame(sendMsg));
    }
@OverridepublicvoidhandlerAdded(ChannelHandlerContextctx) throwsException {
Stringmessage=dateFormat.format(newDate())+":"+ctx.channel().remoteAddress()+" 加入聊天室";
//添加客户端的集合channels.add(ctx.channel());
//自动把消息广播给其客户端channels.writeAndFlush(newTextWebSocketFrame(message));
System.out.println("服务器收到链接 ID="+ctx.channel().id().asLongText());
    }
@OverridepublicvoidhandlerRemoved(ChannelHandlerContextctx) throwsException {
Stringmessage=dateFormat.format(newDate())+":"+ctx.channel().remoteAddress()+" 断开连接";
channels.writeAndFlush(newTextWebSocketFrame(message));
    }
//客户端退出@OverridepublicvoidchannelInactive(ChannelHandlerContextctx) throwsException {
Stringmessage=dateFormat.format(newDate())+":"+ctx.channel().remoteAddress()+" 退出聊天室";
channels.writeAndFlush(newTextWebSocketFrame(message));
System.out.println(message);
    }
@OverridepublicvoidexceptionCaught(ChannelHandlerContextctx, Throwablecause) throwsException {
System.out.println("发生异常 ID="+ctx.channel().id().asLongText()+";msg="+cause.getMessage());
ctx.channel().close();
    }
}
  • DefaultChannelGroup : 该group用来存储所有的客户端的channel
  • channelRead0 : 当接收到请求拿到数据的方法,需要把数据广播给所有客户端

客户端编写

<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><title>WebSocket测试</title></head><body><textareaid="viewBody"rows="10"style="width: 500px"></textarea><br/><inputid="sendInput"type="text"style="width: 450px"><buttonid="sendBtn"onclick="send()">发送</button></body><script>varsocket;
if(!window.WebSocket){
alert("浏览器不支持");
    }else{
//创建客户端socket=newwindow.WebSocket("ws://localhost:8000/hello");
//当收到消息socket.onmessage=function (event) {
varinput=document.getElementById("viewBody");
input.value=input.value+"\n"+event.data;
        }
//打开链接socket.onopen=function (event) {
varinput=document.getElementById("viewBody");
input.value="成功加入聊天室"+"\n";
        }
//关闭链接socket.onclose=function (event) {
varinput=document.getElementById("viewBody");
input.value=input.value+"\n"+"退出聊天室";
        }
functionsend(){
if(socket&&socket.readyState==WebSocket.OPEN){
letsendInput=document.getElementById("sendInput");
letvalue=sendInput.value;
socket.send(value);
sendInput.value="";
            }
        }
    }
</script></html>

测试效果

目录
相关文章
|
3月前
|
前端开发 JavaScript 网络协议
深入理解Python Web开发中的前后端分离与WebSocket实时通信技术
【7月更文挑战第18天】前后端分离采用Flask/Django框架,前端JavaScript框架如Vue.js与后端通过AJAX/Fetch通信。WebSocket提供实时双向通信,Python可借助websockets库或Flask-SocketIO实现。最佳实践包括定义清晰的接口规范,确保安全性(HTTPS,认证授权),优化性能,和健壮的错误处理。结合两者,打造高效实时应用。
77 1
|
5月前
|
缓存 网络协议 算法
Netty的基础入门(上)
Netty的基础入门(上)
188 1
|
4月前
|
JavaScript 网络协议 前端开发
【Nodejs】WebSocket 全面解析+实战演练——(Nodejs实现简易聊天室)
【Nodejs】WebSocket 全面解析+实战演练——(Nodejs实现简易聊天室)
387 0
|
2月前
|
监控 小程序 安全
小程序全栈开发中的WebSocket实时通信实践是一种高效的开发模式。
随着移动互联网的发展,小程序成为企业拓展业务的新渠道。WebSocket作为一种实时通信协议,可在小程序中实现如实时聊天、推送、游戏等功能。它支持客户端与服务器间的全双工长连接通信,优于传统HTTP。开发者需注意安全、性能及兼容性等问题,以优化体验并保障稳定运行。掌握WebSocket有助于提升小程序功能性与用户体验。
40 1
|
2月前
|
前端开发 网络协议 物联网
Django Web:搭建Websocket服务器(入门篇)
Django Web:搭建Websocket服务器(入门篇)
41 1
|
2月前
|
数据处理 开发者 监控
揭秘实时Web应用开发:WebSocket与Akka Streams如何让Play Framework如虎添翼?
【8月更文挑战第31天】实时Web应用需求日益增长,覆盖了从即时通讯到在线游戏等多个领域。Play Framework结合WebSocket与Akka Streams,简化了高效实时应用的开发。WebSocket提供全双工通信,使服务器能主动向客户端推送消息;Akka Streams支持声明式数据流处理,有效避免系统因数据处理不及时而崩溃。本文通过示例代码展示了如何利用这些技术构建实时股票报价系统,展现了其在实时数据处理方面的强大能力。掌握这一技术组合,将大幅提升你在实时Web应用开发中的效率与稳定性。
25 0
|
3月前
|
JavaScript 前端开发 UED
WebSocket在Python Web开发中的革新应用:解锁实时通信的新可能
【7月更文挑战第16天】WebSocket是实现Web实时通信的协议,与HTTP不同,它提供持久双向连接,允许服务器主动推送数据。Python有多种库如websockets和Flask-SocketIO支持WebSocket开发。使用Flask-SocketIO的简单示例包括定义路由、监听消息事件,并在HTML中用JavaScript建立连接。WebSocket提高了实时性、减少了服务器压力,广泛应用于聊天、游戏等场景。
36 1
|
2月前
|
网络协议 前端开发 Go
[go笔记]websocket入门
[go笔记]websocket入门
|
3月前
|
监控 Go
golang开发 gorilla websocket的使用
【7月更文挑战第11天】在Golang中, 使用Gorilla WebSocket库可轻松实现WebSocket通信。安装库: `go get github.com/gorilla/websocket`。创建连接: `websocket.DefaultDialer.Dial(&quot;ws://url&quot;, nil)`。发送消息: `conn.WriteMessage(websocket.TextMessage, []byte(&quot;Hello&quot;))`。接收消息: 循环调用`conn.ReadMessage()`。适用于实时聊天或股票行情等场景。
|
3月前
|
存储 前端开发 Go
golang怎么搭建Websocket聊天室服务端
连接的添加和移除 添加连接: 当一个新的WebSocket连接建立时,服务器需要将这个连接添加到全局的连接列表中。多个连接可能同时建立,从而导致多个并发操作试图修改连接列表。 移除连接: 当一个WebSocket连接断开时,服务器需要将这个连接从全局的连接列表中移除。如果多个连接同时断开,可能会导致并发修改连接列表。