Netty实现对Websocket的支持
一、WebSocket的简介及优势
WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
首先可以看下HTTP协议的有哪些不好的地方:HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。
为了解决这些痛点,WebSocket就应运而生了。WebSocket 连接允许客户端和服务器之间进行全双工通信,以便任一方都可以通过建立的连接将数据推送到另一端。WebSocket 只需要建立一次连接,就可以一直保持连接状态。
二、WebSocket客户端API
2.1 WebSocket 构造函数
var Socket=new WebSocket("ws://localhost:20000/web");
2.2 WebSocket 属性
以下是 WebSocket 对象的属性。假定我们使用了以上代码创建了 Socket 对象:
属性 | 描述 |
---|---|
Socket.readyState | 只读属性 readyState 表示连接状态,可以是以下值:0 - 表示连接尚未建立。1 - 表示连接已建立,可以进行通信。2 - 表示连接正在进行关闭。3 - 表示连接已经关闭或者连接不能打开。 |
Socket.bufferedAmount | 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。 |
2.3 WebSocket 事件
以下是 WebSocket 对象的相关事件。假定我们使用了以上代码创建了 Socket 对象:
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
2.4 WebSocket 方法
以下是 WebSocket 对象的相关方法。假定我们使用了以上代码创建了 Socket 对象:
方法 | 描述 |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
三、WebSocket客户端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Netty WebSocket</title>
</head>
<body>
<br>
<script type="text/javascript">
var websocket;
if(!window.WebSocket){
window.WebSocket=window.MozWebSocket;
}
if(window.WebSocket){
websocket=new WebSocket("ws://localhost:20000/web");
websocket.onmessage=function (event) {
console.log("websocket接受消息"+event.data);
var text=document.getElementById('responseText');
text.value="";
text.value=event.data;
}
websocket.onopen=function (event) {
console.log("websocket打开");
var text=document.getElementById('responseText');
text.value="";
text.value="打开websocket服务正常";
}
websocket.onclose=function (event) {
console.log("websocket关闭");
var text=document.getElementById('responseText');
text.value="";
text.value="关闭websocket服务";
}
websocket.onerror=function (event) {
console.log("websocket异常");
var text=document.getElementById('responseText');
text.value="";
text.value="websocket服务异常"; }
}else{
alert("你的浏览器不支持WebSocket");
} function send(message) {
if(websocket){
if(websocket.readyState==WebSocket.OPEN){
console.log("通过websocket发送消息");
websocket.send(message);
}
}else{
alert("未建立websocket连接");
}
}
</script> <form onsubmit="return false;">
<input type="text" name="message" value="Netty实践"/>
<br><br>
<input type="button" value="发送消息" onclick="send (this.form.message.value)"/>
<h3>应答消息</h3>
<textarea id="responseText" style="width: 500px;height: 300px;"></textarea>
</form> </body>
</html>
四、netty服务端代码
4.1 netty启动类
public class NettyServer { public static void main(String[] args) throws Exception{
//服务器启动
new NettyServer().start(20000);
} public void start(int port) throws Exception{
//用于监听连接的线程组
EventLoopGroup bossGroup=new NioEventLoopGroup();
//用于发送接收消息的线程组
EventLoopGroup workGroup=new NioEventLoopGroup(); try{
//启动类引导程序
ServerBootstrap b=new ServerBootstrap();
//绑定两个线程组
b.group(bossGroup,workGroup);
//设置非阻塞,用它来建立新accept的连接,用于构造serverSocketChannel的工厂类
b.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel){
ChannelPipeline channelPipeline=channel.pipeline();
// HttpServerCodec:将请求和应答消息解码为HTTP消息
channelPipeline.addLast(new HttpServerCodec());
// HttpObjectAggregator:将HTTP消息的多个部分合成一条完整的HTTP消息
channelPipeline.addLast(new HttpObjectAggregator(65536));
// ChunkedWriteHandler:向客户端发送HTML5文件
channelPipeline.addLast(new ChunkedWriteHandler());
//在管道中添加自己实现的Handler处理类
channelPipeline.addLast(new WebsocketServerHandler());
}
});
Channel channel=b.bind(port).sync().channel();
System.out.println("服务器启动端口:"+port);
channel.closeFuture().sync();
}finally {
workGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
} }
}
4.2 netty的业务处理的Handler类
public class WebsocketServerHandler extends SimpleChannelInboundHandler<Object> { private WebSocketServerHandshaker handshaker; @Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
//传统的http接入
if(o instanceof FullHttpRequest){
handleHttpRequest(channelHandlerContext,(FullHttpRequest) o);
}
//webSocket接入
else if(o instanceof WebSocketFrame){
handleWebsocketFrame(channelHandlerContext,(WebSocketFrame) o);
} } @Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
} private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req){
//构造握手响应返回
WebSocketServerHandshakerFactory webSocketServerHandshakerFactory=new WebSocketServerHandshakerFactory("ws://localhost:20000/web",null,false);
handshaker=webSocketServerHandshakerFactory.newHandshaker(req);
handshaker.handshake(ctx.channel(),req); } private void handleWebsocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame){
//判断是否是链路关闭消息
if(frame instanceof CloseWebSocketFrame){
handshaker.close(ctx.channel(),(CloseWebSocketFrame) frame.retain());
return;
}
//判断是否是ping消息
if(frame instanceof PingWebSocketFrame){
ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
return;
}
//文本消息处理
String request=((TextWebSocketFrame)frame).text();
System.out.println("接受的信息是:"+request);
String date=new Date().toString();
//将接收消息写回给客户端
ctx.channel().write(new TextWebSocketFrame("现在时刻:"+date+"发送了:"+request));
}
}
五、运行成功截图
参考资料:
https://www.cnblogs.com/jingmoxukong/p/7755643.html
http://www.ruanyifeng.com/blog/2017/05/websocket.html
Netty实现对Websocket的支持的更多相关文章
- 使用ASP.NET Web API自带的类库实现对CORS的支持(在开发中使用这种方式)(转载)
在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中我们通过自定义的HttpMessageHandler为ASP.NET Web API赋予了跨域资源共享的能力,具体来 ...
- 如何在iOS上实现对HTTPS的支持(转)
原文地址:http://blog.5ibc.net/p/101504.html 首先,需要明确你使用HTTP/HTTPS的用途,因为OSX和iOS平台提供了多种API,来支持不同的用途,官方文档< ...
- qml实现对SSL的支持(使用msys2,同时支持32和64位)超详细 good
首先准备环境.两种方法,使用mingw64 或者VS 直接放上下载地址https://sourceforge.net/projects/msys2/我下载的是msys2-x86_64-20161025 ...
- .net core 和 WPF 开发升讯威在线客服与营销系统:实现对 IE8 的完全完美支持 【干货】
本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf.shengxunwei.com 注意 ...
- Netty对WebSocket的支持(五)
Netty对WebSocket的支持(五) 一.WebSocket简介 在Http1.0和Http1.1协议中,我们要实现服务端主动的发送消息到网页或者APP上,是比较困难的,尤其是现在IM(即时通信 ...
- Google帮助IE浏览器实现对SVG支持
可缩放矢量图形(SVG)的意识就是一个用于描述二维矢量图形的一种开放图形格式. SVG现在已经能够广泛得应用到许多的项目当中,包括KDE和维基百科等.但是 Internet Explorer浏览器的内 ...
- 基于spring-boot和docker-java实现对docker容器的动态管理和监控[附完整源码下载]
(我是个封面) docker简介 Docker 是一个开源的应用容器引擎,和传统的虚拟机技术相比,Docker 容器性能开销极低,因此也广受开发者喜爱.随着基于docker的开发者越来越多,doc ...
- 基于DevExpress实现对PDF、Word、Excel文档的预览及操作处理
http://www.cnblogs.com/wuhuacong/p/4175266.html 在一般的管理系统模块里面,越来越多的设计到一些常用文档的上传保存操作,其中如PDF.Word.Excel ...
- Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问
本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...
随机推荐
- 11.3 free:查看系统内存信息
free命令用于显示系统内存状态,具体包括系统物理内存.虚拟内存.共享内存和系统缓存等. free命令的参数选项及说明 -b 以Byte为单位显示内存的使用情况 -m 以MB为单位显示内存 ...
- Java反射机制详情
1.运行环境 JDK8+lntellij IDEA 2018.3 2.反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个 ...
- 开源项目核心商城(CoreShop)
帮小伙伴推一下他的开源项目作者是@大灰灰 核心商城(CoreShop)Beta 支持可视化布局的.Net小程序商城 [![star](https://gitee.com/CoreUnion/CoreS ...
- TVMNN编译Compiler栈
TVMNN编译Compiler栈 内容纲要 前言 调研目标 TVM介绍 TVM源码架构 FrontEnd Relay BackEnd VTA实现原理及设计思想提炼 整体结构 VTA Hardware ...
- 4D毫米波雷达Radar
4D毫米波雷达Radar 围绕雷达.激光雷达.高精定位等新一代传感器技术将会进入量产周期. 自动驾驶公司的竞争,在传感器配置上坦白说并没有太多差异化.除了车载激光雷达属于近几年的产物,类似摄像头.毫米 ...
- 3DPytorch-API NVIDIA Kaolin
3DPytorch-API NVIDIA Kaolin NVIDIA Kaolin library provides a PyTorch API for working with a variety ...
- RGB-D相机视觉SLAM
RGB-D相机视觉SLAM Dense Visual SLAM for RGB-D Cameras 开源代码地址: vision.in.tum.de/data/software/dvo 摘要 本文提 ...
- GPU编程和流式多处理器(七)
6. 杂项说明 6.1. warp级原语 warp作为执行的原始单元(自然位于线程和块之间),重要性对CUDA程序员显而易见.从SM 1.x开始,NVIDIA开始添加专门针对thread的指令. Vo ...
- 不是都需要ARM吗?
不是都需要ARM吗? ARM系统架构简介 什么是ARM处理器,为什么没有听说? ARM-缩写:Advanced RISC Machines 该处理器起源于1984年的英格兰.在成立之初,ARM代表Ac ...
- Hash源码注释解析
部分代码注释解析: 1 import java.io.IOException; 2 import java.io.InvalidObjectException; 3 import java.io.Se ...