- 浏览: 354636 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
liulehua_123:
...
使用netty+spring搭建游戏框架 -
heng123:
netty等视频java.5d6b.com教程
使用netty+spring搭建游戏框架 -
di1984HIT:
、
redis 主从同步配置方案 -
di1984HIT:
学习了~~
使用netty+spring搭建游戏框架 -
di1984HIT:
不错,学习了~~
征服flume之三——使用log4j输出日志到flume
WebSocket是html5规范新引入的功能,用于解决浏览器与后台服务器双向通讯的问题,使用WebSocket技术,后台可以随时向前端推送消息,以保证前后台状态统一,在传统的无状态HTTP协议中,这是“无法做到”的。
WebSocket提出之前,为了解决后台推送消息到前台的需求,提出了一些解决方案,这些方案使用已有的技术(如ajax,iframe,flashplayer,java applet ...),通过一些变通的处理来实现。
webSocket是html5新引入的技术,允许后台随时向前端发送文本或者二进制消息,WebSocket是一种全新的协议,不属于http无状态协议,协议名为"ws",这意味着一个websocket连接地址会是这样的写法:
ws://127.0.0.1:8080/websocket。ws不是http,所以传统的web服务器不一定支持,需要服务器与浏览器同时支持, WebSocket才能正常运行,目前的支持还不普遍,需要特别的web服务器和现代的浏览器。
浏览器对WebSocket的支持
Google Chrome浏览器最先支持WebSocket,随后是Safari,Firefox,此外最新版本的Opera和IE(Opera11,IE10)也支持WebSocket。
客户端WebSocket的主要方法
1 构造函数
2 事件open/message/close/error
WebSocket#onopen, onmessage, onclose, onerror
连接打开时,回调onopen方法,接收到后台消息时会触发到onmessage事件,后台关闭时调用onclose,出现连接异常时可在onerror中捕获
发送消息 - WebSocket#send(data)
关闭连接 - WebSocket#close(optional code, optional reason)
下面是一个简单的html5连接websocket服务器测试页
服务器对WebSocket的支持
WebSocket不同于http协议,传统的web服务器通常不支持WebSocket.而websocket服务器端的开发大概有借助Socket.IO开发、NodeJS和Socket.IO联合开发以及借助netty框架开发等等。这里只对netty框架下的websocket开发进行一个简单的说明!
websocket的协议比较简单, 客户端和普通的浏览器一样通过80或者443端口和服务器进行请求握手,服务器根据http header识别是否一个websocket请求,如果是,则将请求升级为一个websocket连接,握手成功后就进入双向长连接的数据传输阶段. websocket的数据传输是基于帧的方式: 0x00 表示数据开始, 0xff表示数据结束,数据以utf-8编码.
简单的说,第一次请求客户端发送的是http请求,请求头中包含websocket相关的信息,服务器端对请求进行验证:
验证成功后,将请求升级为一个websocket连接,之后的通信就进入双向长连接的数据传输阶段。
一定要注意在messageReceived中要对HttpRequest和WebSocketFrame分别进行处理。
服务入口
一定要注意的是netty3.0一下的版本是不支持websocket的!我这里用的是3.3.0.Final版本。
可能存在的隐患:不同草案的websocket 握手标准有所不同,因此netty在这方面的检测是否可以满足要求?
我这里也参考了 基于Websocket草案10协议的升级及基于Netty的握手实现,在此对冯立彬的博客表示感谢!
客户端通过服务器端做消息中转就好啦,实现起来并不复杂!
WebSocket提出之前,为了解决后台推送消息到前台的需求,提出了一些解决方案,这些方案使用已有的技术(如ajax,iframe,flashplayer,java applet ...),通过一些变通的处理来实现。
webSocket是html5新引入的技术,允许后台随时向前端发送文本或者二进制消息,WebSocket是一种全新的协议,不属于http无状态协议,协议名为"ws",这意味着一个websocket连接地址会是这样的写法:
ws://127.0.0.1:8080/websocket。ws不是http,所以传统的web服务器不一定支持,需要服务器与浏览器同时支持, WebSocket才能正常运行,目前的支持还不普遍,需要特别的web服务器和现代的浏览器。
浏览器对WebSocket的支持
Google Chrome浏览器最先支持WebSocket,随后是Safari,Firefox,此外最新版本的Opera和IE(Opera11,IE10)也支持WebSocket。
客户端WebSocket的主要方法
1 构造函数
var websocket = new WebSocket("ws://127.0.0.1:8080/websocket");
2 事件open/message/close/error
WebSocket#onopen, onmessage, onclose, onerror
连接打开时,回调onopen方法,接收到后台消息时会触发到onmessage事件,后台关闭时调用onclose,出现连接异常时可在onerror中捕获
发送消息 - WebSocket#send(data)
关闭连接 - WebSocket#close(optional code, optional reason)
下面是一个简单的html5连接websocket服务器测试页
<!DOCTYPE html> <html> <head> <script type="text/javascript" charset="utf-8" > window.WebSocket = window.WebSocket || window.MozWebSocket; if (!window.WebSocket){ alert("WebSocket not supported by this browser"); return; }; var websocket = new WebSocket("ws://127.0.0.1:8080/websocket"); websocket.onmessage = function(evt){ var data = evt.data; alert("received message: " + data); } function send() { var name = document.querySelector("input[name=name]").value; alert("websocket send message:"+name); websocket.send(name); } </script> </head> <body> <label for="name">What’s your name:</label> <input type="text" id="name" name="name" /> <button onclick="send()">Send</button> <div id="message" style="color:red"></div> </body> </html>
服务器对WebSocket的支持
WebSocket不同于http协议,传统的web服务器通常不支持WebSocket.而websocket服务器端的开发大概有借助Socket.IO开发、NodeJS和Socket.IO联合开发以及借助netty框架开发等等。这里只对netty框架下的websocket开发进行一个简单的说明!
websocket的协议比较简单, 客户端和普通的浏览器一样通过80或者443端口和服务器进行请求握手,服务器根据http header识别是否一个websocket请求,如果是,则将请求升级为一个websocket连接,握手成功后就进入双向长连接的数据传输阶段. websocket的数据传输是基于帧的方式: 0x00 表示数据开始, 0xff表示数据结束,数据以utf-8编码.
简单的说,第一次请求客户端发送的是http请求,请求头中包含websocket相关的信息,服务器端对请求进行验证:
private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { // Allow only GET methods. if (req.getMethod() != GET) { sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); return; } // Send the demo page and favicon.ico if (req.getUri().equals("/")) { HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req)); res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); setContentLength(res, content.readableBytes()); res.setContent(content); sendHttpResponse(ctx, req, res); return; } else if (req.getUri().equals("/favicon.ico")) { HttpResponse res = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND); sendHttpResponse(ctx, req, res); return; } // Handshake WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( this.getWebSocketLocation(req), null, false); this.handshaker = wsFactory.newHandshaker(req); if (this.handshaker == null) { wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel()); } else { this.handshaker.handshake(ctx.getChannel(), req); System.out.println(WebSocketServer.recipients.size()); WebSocketServer.recipients.add(ctx.getChannel()); System.out.println(WebSocketServer.recipients.size()); System.out.println(ctx.getChannel().getId()); } }
验证成功后,将请求升级为一个websocket连接,之后的通信就进入双向长连接的数据传输阶段。
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { // Check for closing frame if (frame instanceof CloseWebSocketFrame) { this.handshaker.close(ctx.getChannel(), (CloseWebSocketFrame) frame); return; } else if (frame instanceof PingWebSocketFrame) { ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData())); return; } else if (!(frame instanceof TextWebSocketFrame)) { throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass() .getName())); } // Send the uppercase string back. String request = ((TextWebSocketFrame) frame).getText(); logger.debug(String.format("Channel %s received %s", ctx.getChannel().getId(), request)); // WebSocketServer.recipients.write(new TextWebSocketFrame(request.toUpperCase())); ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase())); }
一定要注意在messageReceived中要对HttpRequest和WebSocketFrame分别进行处理。
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { Object msg = e.getMessage(); if (msg instanceof HttpRequest) { handleHttpRequest(ctx, (HttpRequest) msg); } else if (msg instanceof WebSocketFrame) { handleWebSocketFrame(ctx, (WebSocketFrame) msg); } }
服务入口
package com.etao.mobile.websocket; import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.group.ChannelGroup; import org.jboss.netty.channel.group.DefaultChannelGroup; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; /** * A HTTP server which serves Web Socket requests at: * * http://localhost:8080/websocket * * Open your browser at http://localhost:8080/, then the demo page will be * loaded and a Web Socket connection will be made automatically. * * This server illustrates support for the different web socket specification * versions and will work with: * * <ul> * <li>Safari 5+ (draft-ietf-hybi-thewebsocketprotocol-00) * <li>Chrome 6-13 (draft-ietf-hybi-thewebsocketprotocol-00) * <li>Chrome 14+ (draft-ietf-hybi-thewebsocketprotocol-10) * <li>Chrome 16+ (RFC 6455 aka draft-ietf-hybi-thewebsocketprotocol-17) * <li>Firefox 7+ (draft-ietf-hybi-thewebsocketprotocol-10) * </ul> */ public class WebSocketServer { private final int port; public static ChannelGroup recipients = new DefaultChannelGroup(); public WebSocketServer(int port) { this.port = port; } public void run() { // Configure the server. ServerBootstrap bootstrap = new ServerBootstrap( new NioServerSocketChannelFactory(Executors .newCachedThreadPool(), Executors.newCachedThreadPool())); // Set up the event pipeline factory. bootstrap.setPipelineFactory(new WebSocketServerPipelineFactory()); // Bind and start to accept incoming connections. bootstrap.bind(new InetSocketAddress(port)); System.out.println("Web socket server started at port " + port + '.'); System.out .println("Open your browser and navigate to http://localhost:" + port + '/'); } public static void main(String[] args) { int port; if (args.length > 0) { port = Integer.parseInt(args[0]); } else { port = 8080; } new WebSocketServer(port).run(); } }
一定要注意的是netty3.0一下的版本是不支持websocket的!我这里用的是3.3.0.Final版本。
可能存在的隐患:不同草案的websocket 握手标准有所不同,因此netty在这方面的检测是否可以满足要求?
我这里也参考了 基于Websocket草案10协议的升级及基于Netty的握手实现,在此对冯立彬的博客表示感谢!
- html5test.rar (28.2 KB)
- 下载次数: 1181
评论
5 楼
niuka
2015-08-11
非常好,最近我一直苦于java怎么跟浏览器建立长连接,看了你的分享之后,果然搞定了,谢谢。。。
4 楼
zhaotong2012
2014-06-25
我想问一下 这个我想通过url地址 获取服务器端数据 时时获取 这个可以实现么
3 楼
cpjsjxy
2014-06-11
beyond667 写道
文章不错,也能正常跑。
有个问题,这个demo里是给localhost里发消息的,怎么样像QQ那样点到点发消息呢?
有个问题,这个demo里是给localhost里发消息的,怎么样像QQ那样点到点发消息呢?
客户端通过服务器端做消息中转就好啦,实现起来并不复杂!
2 楼
beyond667
2014-05-28
文章不错,也能正常跑。
有个问题,这个demo里是给localhost里发消息的,怎么样像QQ那样点到点发消息呢?
有个问题,这个demo里是给localhost里发消息的,怎么样像QQ那样点到点发消息呢?
1 楼
syd6815892
2014-02-11
少了JAR包啊
发表评论
-
Java编程规范
2018-05-21 12:59 950Java编程规范 一、 命名约束 1. [强制] 代码中的命名 ... -
java面试整理二——JVM
2018-02-25 16:07 7211. JVM的主要结构 JVM ... -
java 面试整理一——基础知识
2018-02-25 16:04 5981. short s1 = 1; s1 = s1 + 1; ... -
Kafka与Spring的集成
2016-01-15 16:10 10636producer public class KafkaSe ... -
基于jquery mobile+websocket+protocol buffer的IM开发
2016-01-15 10:46 3668第一次研究有关web端的框架,结合工作需要,决定搞一个基于we ... -
linux操作系统下 Jenkins+SVN+Maven+Tomcat 自动集成环境搭建
2016-01-05 15:59 5777一、准备工作 jdk(jdk1.7.0_65.zip) Mav ... -
tcp 连接关闭详解
2014-07-10 14:48 4046主动发起关闭TCP链接端 ... -
Linux下Java线程状态分析
2014-06-11 14:39 5180在Linux上输入top 进入top后按【shift】+【H】 ... -
java面试整理(1)
2012-12-04 15:44 11081. short s1 = 1; s1 = s1 + 1; ... -
Java并发之——同步与原子性
2012-08-27 13:08 1382每一个线程自顾自的做 ... -
spring集成log4j配置信息
2012-07-17 14:32 2263spring中集成log4j并非难事,只需要在web.xml ... -
J2EE开发中的java字符编码问题经验总结
2012-07-16 12:28 1497在J2EE程序开发过程中,经常遇到字符的编码问题。这一问题困扰 ... -
使用 Netty 进行 UDP 网络编程
2012-07-16 11:33 32809使用 Netty 进行 UDP 网络编程 在正式开始 ... -
将json字符串转换为对象
2012-07-13 09:52 1395准备将这几年的工作进行一个系统的总结,会陆续发些东西出来供大家 ... -
使用netty+spring搭建游戏框架
2012-07-12 18:52 51331一、 java NIO简介 nio是java New IO的简 ...
相关推荐
1、基于netty+websocket+springboot的实时聊天系统项目源码.zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料...
netty-websocket-example 基于netty的websocket实现示例 高并发 附jmx压力测试
毕设项目:基于netty+websocket+springboot的实时聊天系统 毕设项目:基于netty+websocket+springboot的实时聊天系统 毕设项目:基于netty+websocket+springboot的实时聊天系统 毕设项目:基于netty+websocket+...
基于Netty5.0的高级案例NettyWebsocket,详情请参见博文:http://blog.csdn.net/l1028386804/article/details/55026558
实现netty作为服务端,websocket连接成功,将channel保存到map集合,通过js发送心跳,服务端接收心跳信息并响应给客户端,当服务端断开时 客户端进行重连操作
这是一个java web项目集成了netty websocket的完整代码。java web项目作为服务器端和客户端进行数据通信。但是常常存在提示Max frame length of 65536 has been exceeded问题。初始化握手对象时指定了...
NettyWebsocket具体案例,主要介绍如何使用Netty开发websocket
Spring+Netty+WebSocket实例,通用性还行,比较贴近生产,注释什么写的比较全
支持WebSocket的浏览器通过webSocket协议发送请求给我们编写的webSocket服务器,服务器对请求消息进行判断,如果是合法的webSocket请求,则获取请求消息体,并在后面追加字符串:“欢迎使用Netty WebSocket 服务,...
使用Netty搭建WebSocket服务器,该资源示范如何修改单包大小限制,解决不能发送大数据包的问题。
netty案例,netty4.1中级拓展篇五《基于Netty搭建WebSocket,模仿微信聊天页面》源码 ...
此资源为websocket的页面源码,配合Spring boot 2基于Netty的高性能Websocket服务器(心跳模式) 文章来使用
NULL 博文链接:https://jdkleo.iteye.com/blog/2396465
spring boot 和 netty 构建长连接通信,通过spring boot 来处理前段请求
简易版netty websocket通讯demo 聊天
springboot+netty+websocket+redis 分布式聊天,实现简单的聊天功能
Netty整合webSocket,Netty整合webSocket,Netty整合webSocket,Netty整合webSocket,Netty整合webSocket
netty实现websocket server。通过构建java客户端程序满足页面的发起websocket请求,实现业务的交互