基于Tomcat7的HTML5 WebSocket 应用示例
作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas、本地存储、多媒体编程接口、WebSocket 等等。这其中有“Web 的 TCP ”之称的 WebSocket 格外吸引开发人员的注意。WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道。Web 开发人员可以非常方便地使用 WebSocket 来构建实时 web 应用。
Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事,但是对于那些实时要求比较高的应用来说,比如说在线游戏、在线证券、设备监控、新闻在线播报、RSS 订阅推送等等,当客户端浏览器准备呈现这些信息的时候,这些信息在服务器端可能已经过时了。所以保持客户端和服务器端的信息同步是实时 Web 应用的关键要素,对 Web 开发人员来说也是一个难题。
在 WebSocket 规范出来之前,开发人员想实现这些实时的 Web 应用,不得不采用一些折衷的方案,其中最常用的就是轮询 (Polling) 和 Comet 技术,而 Comet 技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为流技术。下面我们简单介绍一下这几种技术:
轮询:
这是最早的一种实现实时 Web 应用的方案。客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步。这种同步方案的最大问题是,当客户端以固定频率向服务器发起请求的时候,服务器端的数据可能并没有更新,这样会带来很多无谓的网络传输,所以这是一种非常低效的实时方案。
长轮询:
长轮询是对定时轮询的改进和提高,目地是为了降低无效的网络传输。当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者时间过期,通过这种机制来减少无效的客户端和服务器间的交互。当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提高。
流:
流技术方案通常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务器端的连接不过期。通过这种机制可以将服务器端的信息源源不断地推向客户端。这种机制在用户体验上有一点问题,需要针对不同的浏览器设计不同的方案来改进用户体验,同时这种机制在并发比较大的情况下,对服务器端的资源是一个极大的考验。
综合这几种方案,您会发现这些目前我们所使用的所谓的实时技术并不是真正的实时技术,它们只是在用 Ajax 方式来模拟实时的效果,在每次客户端和服务器端交互的时候都是一次 HTTP 的请求和应答的过程,而每一次的 HTTP 请求和应答都带有完整的 HTTP 头信息,这就增加了每次传输的数据量,而且这些方案中客户端和服务器端的编程实现都比较复杂,在实际的应用中,为了模拟比较真实的实时效果,开发人员往往需要构造两个 HTTP 连接来模拟客户端和服务器之间的双向通讯,一个连接用来处理客户端到服务器端的数据传输,一个连接用来处理服务器端到客户端的数据传输,这不可避免地增加了编程实现的复杂度,也增加了服务器端的负载,制约了应用系统的扩展性。
本文通过一个简单例子来说明在Tomcat7(注:Tomcat7之后才提供WebSocket的支持)上运行一个 WebSocket 应用。
一、WebSocket
WebSocket API是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox 4、Chrome 4、Opera 10.70以及Safari 5等浏览器的支持。
WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。
Ajax技术很聪明的一点是没有设计要使用的方式。WebSocket为指定目标创建,用于双向推送消息。
<!--[if !supportLists]-->二、<!--[endif]-->编写servlet
自定义的servlet必须继承自org.apache.catalina.websocket.WebSocketServlet,下述为完整代码:
package cn.jess.websocket; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.StreamInbound; import org.apache.catalina.websocket.WebSocketServlet; import org.apache.catalina.websocket.WsOutbound; public class EchoServlet extends WebSocketServlet { /** * */ private static final long serialVersionUID = -2581942001009336822L; //private static final Logger log = Logger.getLogger("EchoServlet"); private static List<MessageInbound> socketList = new ArrayList<MessageInbound>(); // privat static final long ser private static List<WebSocketMessageInbound> connsList = new ArrayList<WebSocketMessageInbound>(); protected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request){ return new WebSocketMessageInbound(); } public class WebSocketMessageInbound extends MessageInbound{ protected void onClose(int status){ super.onClose(status); socketList.remove(this); } protected void onOpen(WsOutbound outbound){ super.onOpen(outbound); socketList.add(this); } //@Override protected void onBinaryMessage(ByteBuffer message) throws IOException { // TODO Auto-generated method stub System.out.println("onBinarymessage"); } @Override protected void onTextMessage(CharBuffer message) throws IOException { // TODO Auto-generated method stub for(MessageInbound messageInbound : socketList){ CharBuffer buffer = CharBuffer.wrap(message); WsOutbound outbound = messageInbound.getWsOutbound(); outbound.writeTextMessage(buffer); outbound.flush(); } } } }
三、配置Web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>websocket</servlet-name> <servlet-class>cn.jess.websocket.EchoServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>websocket</servlet-name> <url-pattern>/websocket</url-pattern> </servlet-mapping> </web-app>
四、编写index.html文件
<!DOCTYPE html> <html> <head> <title>WebSockete Demo</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> <script type="text/javascript"> //验证浏览器是否支持WebSocket协议 if(!window.WebSocket){ alert("WebSockeet not supported by this browser!"); } var ws; function display(){ ws = new WebSocket("ws://localhost:8980/WebSocketHTML5/websocket"); //监听消息 ws.onmessage = function(event){ log(event.data); } //关闭WebSocket ws.onclose = function(event){ } //打开WebSocket ws.onopen = function(event){ ws.send("Hello,Server"); } ws.onerror = function(event){ } } var log = function(s){ if(document.readyState !== "complete"){ log.buffer.pust(s); }else{ document.getElementById("contendId").innerHTML += (s + "\n"); } } function sendMsg(){ var msg = document.getElementById("messageId"); ws.send(msg.value); } </script> </head> <body onload="display();"> <div id="valueLabel"></div> <textarea rows="20" cols="30" id="contendId"></textarea> <br/> <input name="message" id="messageId"/> <button id="sendButton" onClick="javascript:sendMsg()">Send</button> </body> </html>
注意:需要拷贝Tomcat7目录下的catalina.jar和tomcat-coyote.jar,在部署时,需要删除程序目录下的catalina.jar,否则会导致servlet加载不成功。
相关推荐
要求tomcat7.0.47以上
Web项目的前后端WebSocket的Java和Tomcat7的使用示例,可以参考本样例来实现WebSocket技术的Web前后台的技术。
html5的websocket代码示例包括错误解决方案
可惜现在不是所有浏览器都支持HTML5,本例是对TOMCAT7.0.32自带的WebSocket功能展示,一个非常简单的聊天室。 代码说明 1、因为本例只做功能展示,所以使用最为精简的代码,只写了2个类和一个JSP,另外使用到TOMCAT7...
java简单的websocket示例,需要tomcat-api.jar tomcat-juli.jar tomcat-coyote.jar
该rar包中的两个jar包是驱动包,此websocket必须在支持的服务器中运行,截至目前,tomcat 7支持的。如果你要跑程序时,必须把jar包去掉。不然会冲突,导致报错
1. Websocket 编程,包括基于Tomcat8的文本和二进制读写,和浏览器端的编程 2. 提供贪吃蛇案例,包括服务端程序和网页端,服务端是控制蛇运动方向的 3. 提供嵌入式端能过Websocket控制灯亮度,嵌入式代码另外上传
apache-tomcat-websocwebsocket的apache tomcat应用示例(现在最新版的tomcat相关接口有改动)
websocket 示例聊天功能,部署tomcat7下,jdk1.7
webSocketDemo,tomcat8 方式, 最最简单的webSocket示例,请用支持html5的浏览器访问页面
Tomcat8WebSockets Tomcat8WebSockets 示例
JAVA的WebSocket示例 需要apache-tomcat-7.0.81以上版本 需要引入tomcat下lib包里面的websocket-api.jar和tomcat7-websocket.jar
此 git 存储库是一个示例应用程序,可帮助您开始在 Red Hat 的 OpenShift PaaS 上使用 Tomcat7。 在 OpenShift 上运行 Tomcat7 的步骤 在创建一个帐户 创建一个命名空间,如果你还没有这样做的话 rhc domain ...
昨天使用HTML5的websocket与Tomcat实现了多人聊天,那是最简单也是最基本的,其中注意的就是开发环境,要满足jdk1.7和tomcat8,当然了tom7 的7.063也行! 今天是国庆的最后一天,苦逼的加班,继续搞代码!令人欣慰的...
Spring WebSocket 示例 描述 这是一个使用 Spring WebSocket 4.0.0 RELEASE 的 WebSocket 服务器的小...安装应用程序的最简单方法是将打包的 war 文件复制到 WebSocket Compliant Server,例如 Jetty 或 Tomcat。 享受
本文介绍了HTML5WebSocket的由来,运作机制及客户端和服务端的API实现,重点介绍服务端(基于Tomcat7)及客户端(基于浏览器原生HTML5API)实现的详细步骤;并通过实际客户案例描述了客户端如何在WebSocket架构下...
适用于Liferay 7的幼稚WebSocket桥 关于如何将JSR-356 WebSocket连接桥接到Liferay 7中的OSGi框架的一个巧妙但实用的草图。仅在捆绑了Tomcat的Alpha-1上进行了测试,并依赖于容器来提供JSR-356 API。 使用Java 8...
数据推送示例说明 (1)项目目标:日志实时展现 (2)实现过程:后台模拟生成动态日志,...(3)客户端所用技术:html5 websocket, 服务器端技术:spring websocket (spring 4.0版以上支持) (4) tomcat7 jdk7 maven
基于 Java Web 项目的 SpringBoot 框架初始化模板,该模板整合了常用的框架,保证大家在此...19、基于 Netty 的 WebSocket 全双工通信设计示例 20、对象存储、消息队列、缓存、分布式锁、限流、国际化、网络等工具类
欢迎使用Apache Tomcat!它是什么? ApacheTomcat:registered:软件... Apache Tomcat软件为各种行业和组织中的众多大型,关键任务Web应用程序提供支持。 上列出了其中一些用户及其故事。 Apache Tomcat,Tomcat,Apache