基于tomcat运行HTML5 WebSocket echo例子

一:概述

作为HTML5新特性之一的WebSocket组件,在实时性有一定要求的WEB应用开发中还是有一定用武之地,高版本的IE、Chrome、FF浏览器都支持Websocket,标准的Websocket通信是基于RFC6455实现服务器端与客户端握手与消息接发的。如果对Websocket通信不是太理解,可以查看RFC文档即可,简单说就是通过发送HTTP请求,实现双方握手,将无状态的HTTP通信协议进一步升级成有状态的通信协议,同时Websocket还支持子协议选项与安全传输。标准的websocket连接URL以ws开头,如果是基于TLS的则以wss开头。基于Websocket可以很方便的开发基于web聊天程序,各种网页消息通知与推送通知。

如果非要扒一扒websocket的今生前世的话,还记得最早的基于HTTP轮询实现网页即时通信的方式,那种做法比较消耗资源、于是有人改进了编程CometD长连接方式,可是本质上还是换汤不换药,而websocket的出现正好解决了这些问题,但是很多浏览器的低版本还是不支持websocket,于是还催生了一些基于websocket理念实现的JS通信框架,其中学得比较像的有SockJS与socket.io,他们都号称支持websocket,然后如果浏览器端不支持原生的websocket,它们会自动启用fallback选项使用其它诸如ajax、Http轮询、长轮询/连接、甚至是flash的socket等机制实现模拟websocket的工作方式,但是他们最大的弊端是如果客户端使用了这些框架,服务器必须用它们,否则等待开发者就是一大堆无法回避的问题,同时很多都是无解的。主要原因在于它们实现自己的协议集,不照它们的格式处理数据没法玩。闲话说的有点多。

二 : 实现步骤

Tomcat7的高版本中实现了websocket服务器端RFC6455标准协议,可以跟浏览器端websocket进行通信,首先要做好如下几步:

1.      安装高版本JDK – JDK8

2.      安装tomcat 7.0.64

3.      在eclipse中建立一个动态的web项目

根据JSR标准,Java中实现websocket的标准接口可以基于注解方式,tomcat也搞好了,只有我们实现如下代码,即可创建一个websocket回声服务器:

package com.websocket.demo;

import java.io.IOException;
import java.nio.ByteBuffer;

import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/echo")
public class EchoExample {

	@OnMessage
	public void echoTextMessage(Session session, String msg, boolean last) {
		try {
			if (session.isOpen()) {
				System.out.println("received from client message = " + msg);
				session.getBasicRemote().sendText(msg, last);
			}
		} catch (IOException e) {
			try {
				session.close();
			} catch (IOException e1) {
			}
		}
	}

	@OnOpen
    public void openConn(Session session) throws IOException {
    	session.getBasicRemote().sendText("hello web socket"); // means open it
    }

    @OnMessage
    public void echoBinaryMessage(Session session, ByteBuffer bb, boolean last) {
    	System.out.println("send binary message...");
        try {
            if (session.isOpen()) {
            	System.out.println("byte buffer lenghth : " + bb.array().length);
            	System.out.println("byte buffer content: " + ((bb.array()[0]) & 0xff));
            	System.out.println("byte buffer content: " + ((bb.array()[1]) & 0xff));
            	System.out.println("byte buffer content: " + ((bb.array()[2]) & 0xff));
                session.getBasicRemote().sendBinary(bb, last);
            }
        } catch (IOException e) {
            try {
                session.close();
            } catch (IOException e1) {
                // Ignore
            }
        }
    }

}

如何在tomcat中启动websocket服务器,首先需要在web.xml添加如下配置:

	<listener>
		<listener-class>org.apache.tomcat.websocket.server.WsContextListener</listener-class>
	</listener>

然后实现ServerApplicationConfig接口,实现如下:

/*
 *
 */
package com.config.websocket.client;

import java.util.HashSet;
import java.util.Set;

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;

public class ScanWebSocketSeverConfig implements ServerApplicationConfig {

	@Override
	public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> scanned) {

		Set<ServerEndpointConfig> result = new HashSet<ServerEndpointConfig>();
/*		if (scanned.contains(EchoWsChatSever.class)) {
			result.add(ServerEndpointConfig.Builder.create(EchoWsChatSever.class, "/echo").build());
		}*/
		return result;
	}

	@Override
	public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
		Set<Class<?>> results = new HashSet<Class<?>>();
		for (Class<?> clazz : scanned) {
			if (clazz.getPackage().getName().startsWith("com.websocket.")) {
				System.out.println("find end point : " + clazz.getName());
				results.add(clazz);
			}
		}
		return results;
	}
}

创建网页echo.html,内容如下:

<html>
<head>
<title>Web Socket Echo Test</title>
<script>
        var ws = null;
		var count = 0;
        function setConnected(connected) {
            document.getElementById(‘connect‘).disabled = connected;
            document.getElementById(‘disconnect‘).disabled = !connected;
            document.getElementById(‘echo‘).disabled  = !connected;
        }

        function connect() {
            var target = document.getElementById(‘target‘).value;
            if (target == ‘‘) {
                alert(‘Please select server side connection implementation.‘);
                return;
            }

            if (‘WebSocket‘ in window) {
                ws = new WebSocket(target);
            } else if (‘MozWebSocket‘ in window) {
                ws = new MozWebSocket(target);
            } else {
                alert(‘WebSocket is not supported by this browser.‘);
                return;
            }

            ws.onopen = function () {
                setConnected(true);
                log(‘Info: WebSocket connection opened.‘);
            };
            ws.onmessage = function (event) {
                log(‘Received: ‘ + event.data);
                if(event.data instanceof ArrayBuffer)
               	{
                	var bytes = new Uint8Array(event.data);
                	alert(bytes.length + " : " + bytes[0]);
               	}
            };
            ws.onclose = function (event) {
                setConnected(false);
                log(‘Info: WebSocket connection closed, Code: ‘ + event.code + (event.reason == "" ? "" : ", Reason: " + event.reason));
            };

        }

        function disconnect() {
            if (ws != null) {
            	ws.doClose();
            	ws = null;
            }
            setConnected(false);
        }

        function echo() {
            if (ws != null) {
                var message = document.getElementById(‘message‘).value;
                log(‘Sent: ‘ + message);
                ws.send(JSON.stringify({‘textMessage‘: message}));
                count++
            } else {
                alert(‘WebSocket connection not established, please connect.‘);
            }
        }

        function log(message) {
            var echomsg = document.getElementById(‘echomsg‘);
            var p = document.createElement(‘p‘);
            p.style.wordWrap = ‘break-word‘;
            p.appendChild(document.createTextNode(message));
            echomsg.appendChild(p);
            while (echomsg.childNodes.length > 25) {
            	echomsg.removeChild(console.firstChild);
            }
            echomsg.scrollTop = console.scrollHeight;
        }

        document.addEventListener("DOMContentLoaded", function() {
            // Remove elements with "noscript" class - <noscript> is not allowed in XHTML
            var noscripts = document.getElementsByClassName("noscript");
            for (var i = 0; i < noscripts.length; i++) {
                noscripts[i].parentNode.removeChild(noscripts[i]);
            }
        }, false);
</script>
</head>
<body>
	<div>
		<h4>URL - ws://localhost:8080/websocket/echo</h4>
		<input id="target" type="text" size="40" style="width: 350px" />
	</div>
	<div>
		<button id="connect" onclick="connect();">Connect</button>
		<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
	</div>
	<div>
		<textarea id="message" style="width: 350px">Here is a message!</textarea>
	</div>
	<div>
		<button id="echo" onclick="echo();" disabled="disabled">Echo message</button>
	</div>
	<div id="echomsg">
	</div>
</body>
</html>

三 :运行与测试

打包部署到tomcat之后,启动chrom浏览器,输入地址:

http://localhost:8080/websocket/echo.html

后来,我还发现,tomcat实现websocket服务器端居然不支持子协议

跟3W上的测试URL结果不一样。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 08:03:04

基于tomcat运行HTML5 WebSocket echo例子的相关文章

基于构建实时WEb应用的HTML5 WebSocket协议&lt;二&gt;

前面说了那么多的理论,我们来看下代码学习. WebSocketAPI简介 首先看一段简单的javascript代码,该代码调用了WebSockets的API. var ws = new WebSocket("ws://echo.websocket.org"); ws.onopen = function(){ws.send("Test!"); }; ws.onmessage = function(evt){console.log(evt.data);ws.close(

Docker学习笔记之二,基于Dockerfile搭建JAVA Tomcat运行环境

前言 在第一篇文字中,我们完全人工方式,一个命令一个命令输入,实现一个 java tomcat运行环境,虽然也初见成效,但很累人.如果依靠依靠脚本构建一个Tomcat容器实例,一个命令可以搞定,何乐而不为呢.好在Docker提 供了Dockerfile作为构建Docker镜像脚本,避免人们一行一行的输入,真是善莫大焉.Dockerfile脚本可以做到随时维护修改,即可以 分享,更有利于在模板化,更不用说传输了,好处那是一大箩筐! 最终目的:打造一个支持SSH终端登录.Tomcat7自动运行的Do

基于Dockerfile搭建JAVA Tomcat运行环境

前言 在第一篇文字中,我们完全人工方式,一个命令一个命令输入,实现一个java tomcat运行环境,虽然也初见成效,但很累人.如果依靠依靠脚本构建一个Tomcat容器实例,一个命令可以搞定,何乐而不为呢.好在Docker提供了Dockerfile作为构建Docker镜像脚本,避免人们一行一行的输入,真是善莫大焉.Dockerfile脚本可以做到随时维护修改,即可以分享,更有利于在模板化,更不用说传输了,好处那是一大箩筐! 最终目的:打造一个支持SSH终端登录.Tomcat7自动运行的Docke

基于构建实时WEb应用的HTML5 WebSocket协议&lt;一&gt;

前言 作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas.本地存储.多媒体编程接口.WebSocket 等等.这其中有"Web 的 TCP "之称的 WebSocket格外吸引开发人员的注意.WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道.WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,Web 开发人员可以非常方便地使用 WebS

使用 HTML5 WebSocket 构建实时 Web 应用

作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas.本地存储.多媒体编程接口.WebSocket 等等.这其中有"Web 的 TCP "之称的 WebSocket 格外吸引开发人员的注意.WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道.Web 开发人员可以非常方便地使用 WebSocket 构建实时 web 应用,开发人员的手中从此又多了一柄神兵利器.本文首先介绍

初识html5 WebSocket

1.  WebSocket概念 WebSocket是HTML5开始提供的一种Client与Server间进行全双工(full-duplex)通讯的网络技术 双工(duplex),指二台通讯设备之间,允许有双向的资料传输 Client和Server通过WebSocket Protocol建立连接后,双方可以互传数据并且双方都可以关闭此连接 2. HTTP概念 HTTP Protocol是无状态协议的,Client和Server通过HTTP Protocol建立连接后,将采用"request-res

Tomcat如何实现WebSocket

WebSocket协议属于HTML5标准,越来越多浏览器已经原生支持WebSocket,它能让客户端和服务端实现双向通信.在客户端和服务器端建立一条WebSocket连接后,服务器端消息可直接发送到客户端,从而打破传统的请求响应模式,避免了无意义的请求.比如传统的方式可能会使用AJAX不断请求服务器端,而WebSocket则可以直接发送数据到客户端且客户端不必请求.同时,由于有了浏览器的原生支持,编写客户端应用程序也变得更加便捷且不必依赖第三方插件.另外,WebSocket协议摒弃了HTTP协议

[转]使用 HTML5 WebSocket 构建实时 Web 应用

HTML5 WebSocket 简介和实战演练 本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例来充分展示 WebSocket 的强大和易用. 作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas.本地存储.多媒体编程接口.WebSocket 等等.这其中有“Web 的 TCP ”之称的 WebSocket 格外吸引开发人员的注意.WebSocket 的出现使得浏

[转]Docker学习笔记之一,搭建一个JAVA Tomcat运行环境

本文转自:http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html 前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序,并通过配置文件可以轻松实现应用程序的自动化安装.部署和升级,非常方便.因为使用了容器,所以可以很方便的把生产环境和开发环境分开,互不影响,这是 docker 最普遍的一个玩法.更多的玩法还有大规模 web 应用.数据库部署.持续