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>

测试效果

目录
相关文章
|
4月前
|
前端开发 JavaScript 网络协议
深入理解Python Web开发中的前后端分离与WebSocket实时通信技术
【7月更文挑战第18天】前后端分离采用Flask/Django框架,前端JavaScript框架如Vue.js与后端通过AJAX/Fetch通信。WebSocket提供实时双向通信,Python可借助websockets库或Flask-SocketIO实现。最佳实践包括定义清晰的接口规范,确保安全性(HTTPS,认证授权),优化性能,和健壮的错误处理。结合两者,打造高效实时应用。
95 1
|
5天前
|
消息中间件 编解码 网络协议
Netty从入门到精通:高性能网络编程的进阶之路
【11月更文挑战第17天】Netty是一个基于Java NIO(Non-blocking I/O)的高性能、异步事件驱动的网络应用框架。使用Netty,开发者可以快速、高效地开发可扩展的网络服务器和客户端程序。本文将带您从Netty的背景、业务场景、功能点、解决问题的关键、底层原理实现,到编写一个详细的Java示例,全面了解Netty,帮助您从入门到精通。
22 0
|
1月前
|
网络协议 前端开发 JavaScript
WebSocket 教程汇总指南,从入门到熟练
本文将带你从零开始,逐步掌握 WebSocket 的基本概念、实现方法和应用场景,通过一系列详细的教程和实践案例,帮助你从入门到熟练地使用 WebSocket 技术。无论你是初学者还是有一定经验的开发者,本文都能为你提供有价值的信息和指导。
|
1月前
|
监控 小程序 前端开发
小程序全栈开发中的WebSocket实时通信实践
【10月更文挑战第3天】随着移动互联网的发展,小程序因便捷的用户体验和社交传播能力,成为企业拓展业务的新渠道。本文探讨了小程序全栈开发中的WebSocket实时通信实践,包括其实时通信、长连接及双向通信的特点,并通过实时聊天、推送、游戏和监控等功能的实现,展示了WebSocket在小程序中的应用。开发者需注意安全性、性能及兼容性等问题,以保障小程序的稳定运行和用户体验。
44 7
|
30天前
|
网络协议 安全 JavaScript
Web实时通信的学习之旅:WebSocket入门指南及示例演示
Web实时通信的学习之旅:WebSocket入门指南及示例演示
121 0
|
3月前
|
监控 小程序 安全
小程序全栈开发中的WebSocket实时通信实践是一种高效的开发模式。
随着移动互联网的发展,小程序成为企业拓展业务的新渠道。WebSocket作为一种实时通信协议,可在小程序中实现如实时聊天、推送、游戏等功能。它支持客户端与服务器间的全双工长连接通信,优于传统HTTP。开发者需注意安全、性能及兼容性等问题,以优化体验并保障稳定运行。掌握WebSocket有助于提升小程序功能性与用户体验。
50 1
|
3月前
|
API 开发者
Netty运行原理问题之Netty实现低开发门槛的问题如何解决
Netty运行原理问题之Netty实现低开发门槛的问题如何解决
|
3月前
|
前端开发 网络协议 物联网
Django Web:搭建Websocket服务器(入门篇)
Django Web:搭建Websocket服务器(入门篇)
66 1
|
3月前
|
数据处理 开发者 监控
揭秘实时Web应用开发:WebSocket与Akka Streams如何让Play Framework如虎添翼?
【8月更文挑战第31天】实时Web应用需求日益增长,覆盖了从即时通讯到在线游戏等多个领域。Play Framework结合WebSocket与Akka Streams,简化了高效实时应用的开发。WebSocket提供全双工通信,使服务器能主动向客户端推送消息;Akka Streams支持声明式数据流处理,有效避免系统因数据处理不及时而崩溃。本文通过示例代码展示了如何利用这些技术构建实时股票报价系统,展现了其在实时数据处理方面的强大能力。掌握这一技术组合,将大幅提升你在实时Web应用开发中的效率与稳定性。
36 0
|
4月前
|
JavaScript 前端开发 UED
WebSocket在Python Web开发中的革新应用:解锁实时通信的新可能
【7月更文挑战第16天】WebSocket是实现Web实时通信的协议,与HTTP不同,它提供持久双向连接,允许服务器主动推送数据。Python有多种库如websockets和Flask-SocketIO支持WebSocket开发。使用Flask-SocketIO的简单示例包括定义路由、监听消息事件,并在HTML中用JavaScript建立连接。WebSocket提高了实时性、减少了服务器压力,广泛应用于聊天、游戏等场景。
46 1