详解WebSocket+spring示例demo(已使用sockJs库)

1、简介

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

Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事,但是对于那些实时要求比较高的应用来说,比如说在线游戏、在线证券、设备监控、新闻在线播报、RSS订阅推送等等,当客户端浏览器准备呈现这些信息的时候,这些信息在服务器端可能已经过时了。

所以保持客户端和服务器端的信息同步是实时 Web应用的关键要素,对 Web开发人员来说也是一个难题。在 WebSocket规范出来之前,开发人员想实现这些实时的Web应用,不得不采用一些折衷的方案,其中最常用的就是轮询(Polling)和 Comet 技术,而Comet技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为流技术。

Html5 WebSocket 设计出来的目的就是要取代轮询和 Comet技术,使客户端浏览器具备像 C/S架构下桌面系统的实时通讯能力。浏览器通过JavaScript向服务器发出建立 WebSocket连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP连接直接交换数据。因为 WebSocket连接本质上就是一个TCP连接,所以在数据传输的稳定性和数据传输量的大小方面,和轮询以及Comet技术比较,具有很大的性能优势。

但是鉴于web socket 对浏览器要求比较高,为了解决这个问题,推出了sockJS,SockJS是一个JavaScript库,提供跨浏览器javascript的API,创建了一个低延迟、全双工的浏览器和web服务器之间通信通道。

2、相关环境要求

Spring4.0.6(要选择4.0+),tomcat7.0.55版本,JDK1.7。

3、具体代码

(以下代码亲测可用!)

(1)web.xml:

<?xmlversionxmlversion="1.0"encoding="UTF-8"?>
<web-app version="3.1"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
 <description>用来测试WebSocket基础上推送的功能</description>
 <distributable/>
 <filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <async-supported>true</async-supported>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
   <param-name>forceEncoding</param-name>
   <param-value>true</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 <!-- Spring 刷新Introspector防止内存泄露 -->
 <listener>
  <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
 </listener>
 <servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:dispatcher-servlet.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
  <async-supported>true</async-supported>
 </servlet>
 <servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>
 <session-config>
  <session-timeout>
   30
  </session-timeout>
 </session-config>
 <welcome-file-list>
  <welcome-file>testSocket.jsp</welcome-file>
 </welcome-file-list>
</web-app>

(2) dispatcher-servlet.xml

<?xmlversionxmlversion="1.0"encoding="UTF-8"?>
<beans:beansxmlnsbeans:beansxmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 <annotation-driven/>
 <!-- 自动扫描的包名 -->
 <context:component-scanbase-packagecontext:component-scanbase-package="zyy.sockjs.config"></context:component-scan>
</beans:beans>

(3)HandshakeInterceptor.java

package zyy.sockjs.config;
import java.util.Map;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; 

@Component
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
 ServerHttpResponse response, WebSocketHandler wsHandler,
 Map<String, Object> attributes) throws Exception {
 System.out.println("Before Handshake");
 return super.beforeHandshake(request,response,wsHandler,attributes);
} 

@Override
public void afterHandshake(ServerHttpRequest request,
 ServerHttpResponse response, WebSocketHandler wsHandler,
 Exception ex) {
 System.out.println("After Handshake");
 super.afterHandshake(request,response,wsHandler,ex);
}
}

(4)InfoSocketEndPoint.Java

package zyy.sockjs.config;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler; 

@Component
public class InfoSocketEndPoint extends TextWebSocketHandler {
public InfoSocketEndPoint() {
} 

@Override
protected void handleTextMessage(WebSocketSession session,
 TextMessage message) throws Exception {
 super.handleTextMessage(session, message);
 TextMessage returnMessage = new TextMessage(message.getPayload()
 + " received at server");
 session.sendMessage(returnMessage);
}
}

(5)SystemWebSocketHandler.java

package zyy.sockjs.config;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
/**
*
* @author dayu
*/ 

@Component
public class SystemWebSocketHandler implements WebSocketHandler {
 @Override
 public void afterConnectionEstablished(WebSocketSession session) throws Exception {
  System.out.println("connect to the websocket success......");
  session.sendMessage(new TextMessage("Server:connected OK!"));
 } 

 @Override
 public void handleMessage(WebSocketSession wss, WebSocketMessage<?> wsm) throws Exception {
  TextMessage returnMessage = new TextMessage(wsm.getPayload()
  + " received at server");
  wss.sendMessage(returnMessage);
 } 

 @Override
 public void handleTransportError(WebSocketSession wss, Throwable thrwbl) throws Exception {
  if(wss.isOpen()){
   wss.close();
  }
  System.out.println("websocket connection closed......");
 } 

 @Override
 public void afterConnectionClosed(WebSocketSession wss, CloseStatus cs) throws Exception {
  System.out.println("websocket connection closed......");
 } 

 @Override
 public boolean supportsPartialMessages() {
  return false;
 }
}

(6)WebSocketConfig.java

package zyy.sockjs.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; 

@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements
  WebSocketConfigurer {
 public WebSocketConfig() {
 } 

 @Override
 public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
  registry.addHandler(systemWebSocketHandler(), "/websck").addInterceptors(new HandshakeInterceptor());
  System.out.println("registed!");
  registry.addHandler(systemWebSocketHandler(), "/sockjs/websck/info").addInterceptors(new HandshakeInterceptor())
    .withSockJS();
 } 

 @Bean
 public WebSocketHandler systemWebSocketHandler() {
  return new SystemWebSocketHandler();
 }
}

(7)testSocket.jsp

<%@ page language="java"contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE htmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=ISO-8859-1">
<title>WebSocket/SockJS Echo Sample (Adapted from Tomcat's echo sample)</title>
 <style type="text/css">
  #connect-container {
   float: left;
   width: 400px
  }
  #connect-container div {
   padding: 5px;
  }
  #console-container {
   float: left;
   margin-left: 15px;
   width: 400px;
  }
  #console {
   border:1px solid #CCCCCC;
   border-right-color:#33333333;
   border-bottom-color:#999999;
   height: 170px;
   overflow-y: scroll;
   padding: 5px;
   width: 100%;
  }
  #console p {
   padding: 0;
   margin: 0;
  }
 </style>
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<script type="text/javascript">
  var ws = null;
  var url = null;
  var transports = [];
  function setConnected(connected) {
   document.getElementById('connect').disabled = connected;
   document.getElementById('disconnect').disabled = !connected;
   document.getElementById('echo').disabled = !connected;
  }
  function connect() {
   if (!url) {
   log('Select whether to use W3C WebSocket or SockJS');
    return;
   }
   //ws = (url.indexOf('sockjs') != -1) ?new SockJS(url, undefined, {protocols_whitelist: transports}) : new WebSocket(url);
   if ('WebSocket'in window) {
    ws= new WebSocket("ws://localhost:8080/SpringSocketJs/websck");
   }else {
    ws = new SockJS("http://localhost:8080/SpringSocketJs/sockjs/websck/info");
   }
   //websocket = new SockJS("http://localhost:8084/SpringWebSocketPush/sockjs/websck");
   ws.onopen = function () {
    setConnected(true);
    //log('Info: connection opened.');
   };
   ws.onmessage = function (event) {
    log('Received: ' + event.data);
   };
   ws.onclose = function (event) {
    setConnected(false);
    log('Info: connection closed.');
    log(event);
   };
  }
  function disconnect() {
   if (ws != null) {
    ws.close();
    ws = null;
   }
   setConnected(false);
  }
  function echo() {
   if (ws != null) {
    var message = document.getElementById('message').value;
    log('Sent: ' + message);
    ws.send(message);
   } else {
    alert('connection not established, please connect.');
   }
  }
  function updateUrl(urlPath) {
   if (urlPath.indexOf('sockjs') != -1) {
    url = urlPath;
    document.getElementById('sockJsTransportSelect').style.visibility ='visible';
   }
   else {
    if (window.location.protocol =='http:') {
     url = 'ws://' + window.location.host + urlPath;
    } else {
     url = 'wss://' + window.location.host + urlPath;
    }
    document.getElementById('sockJsTransportSelect').style.visibility ='hidden';
   }
  }
  function updateTransport(transport) {
   transports = (transport == 'all') ? [] : [transport];
  }
  function log(message) {
   var console = document.getElementById('console');
   var p = document.createElement('p');
   p.style.wordWrap = 'break-word';
   p.appendChild(document.createTextNode(message));
   console.appendChild(p);
   while (console.childNodes.length > 25) {
    console.removeChild(console.firstChild);
   }
   console.scrollTop = console.scrollHeight;
  }
 </script>
</head>
<body>
<noscript><h2 style="color:#ff0000">Seems your browser doesn't supportJavascript!Websockets
 rely on Javascript being enabled. Please enable
 Javascript and reload this page!</h2></noscript>
<div>
 <div id="connect-container">
  <input id="radio1"type="radio"name="group1"onclick="updateUrl('/SpringSocketJs/websocket');">
   <label for="radio1">W3C WebSocket</label>
  <br>
  <input id="radio2"type="radio"name="group1"onclick="updateUrl('/SpringSocketJs/sockjs/websocket');">
   <label for="radio2">SockJS</label>
  <div id="sockJsTransportSelect" style="visibility:hidden;">
   SockJS transport:
   <select onchange="updateTransport(this.value)">
    <option value="all">all</option>
    <option value="websocket">websocket</option>
    <option value="xhr-polling">xhr-polling</option>
    <option value="jsonp-polling">jsonp-polling</option>
    <option value="xhr-streaming">xhr-streaming</option>
    <option value="iframe-eventsource">iframe-eventsource</option>
    <option value="iframe-htmlfile">iframe-htmlfile</option>
   </select>
  </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>
 <div id="console-container">
  <div id="console"></div>
 </div>
</div>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2017-01-17

Python通过websocket与js客户端通信示例分析

具体的 websocket 介绍可见 http://zh.wikipedia.org/wiki/WebSocket 这里,介绍如何使用 Python 与前端 js 进行通信. websocket 使用 HTTP 协议完成握手之后,不通过 HTTP 直接进行 websocket 通信. 于是,使用 websocket 大致两个步骤:使用 HTTP 握手,通信. js 处理 websocket 要使用 ws 模块: Python 处理则使用 socket 模块建立 TCP 连接即可,比一般的 soc

JS实现websocket长轮询实时消息提示的效果

效果图如下: 参考代码如下: jsp代码: <%@ page contentType="text/html;charset=UTF-8" language="java"%> <div class="page-header navbar navbar-fixed-top"> <div class="page-header-inner"> <div class="page-log

浅析nodejs实现Websocket的数据接收与发送

WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术.在WebSocket API中,浏览器和服务器只需要要做一个握手(handshaking)的动作,然后,浏览器和服务器之间就形成了一条快速通道.两者之间就直接可以数据互相传送. WebSocket是一个通信的协议,分为服务器和客户端.服务器放在后台,保持与客户端的长连接,完成双方通信的任务.客户端一般都是实现在支持HTML5浏览器核心中,通过提供JavascriptAPI使用网页可以建立websocket连接.

基于html5和nodejs相结合实现websocket即使通讯

最近都在学习HTML5,做canvas游戏之类的,发现HTML5中除了canvas这个强大的工具外,还有WebSocket也很值得注意.可以用来做双屏互动游戏,何为双屏互动游戏?就是通过移动端设备来控制PC端网页游戏.这样的话就要用到实时通讯了,而WebSocket无疑是最合适的.WebSocket相较于HTTP来说,有很多的优点,主要表现在WebSocket只建立一个TCP连接,可以主动推送数据到客户端,而且还有更轻量级的协议头,减少数据传送量.所以WebSocket暂时来说是实时通讯的最佳协

JavaScript之WebSocket技术详解

概述 HTTP协议是一种无状态协议,服务器端本身不具有识别客户端的能力,必须借助外部机制,比如session和cookie,才能与特定客户端保持对话.这多多少少带来一些不便,尤其在服务器端与客户端需要持续交换数据的场合(比如网络聊天),更是如此.为了解决这个问题,HTML5提出了浏览器的WebSocket API. WebSocket的主要作用是,允许服务器端与客户端进行全双工(full-duplex)的通信.举例来说,HTTP协议有点像发电子邮件,发出后必须等待对方回信:WebSocket则是

Javascript WebSocket使用实例介绍(简明入门教程)

一旦你了解了网络套接字与WEB服务器的连接,你将可以从浏览器发送数据到服务器并且可以接收由服务器返回的响应数据. 以下是创建一个新的WebSocket对象的API: 复制代码 代码如下: var Socket = new WebSocket(url, [protocal] ); 这里第一个参数是指要连接的URL,第二个参数是可选的,如果需要的话,则是指定一个的服务器支持的协议. WEB Socket属性: 属性 说明 Socket.readyState readyState的代表的ReadOnl

Python简明入门教程

本文实例讲述了Python简明入门教程.分享给大家供大家参考.具体如下: 一.基本概念 1.数 在Python中有4种类型的数--整数.长整数.浮点数和复数. (1)2是一个整数的例子. (2)长整数不过是大一些的整数. (2)3.23和52.3E-4是浮点数的例子.E标记表示10的幂.在这里,52.3E-4表示52.3 * 10-4. (4)(-5+4j)和(2.3-4.6j)是复数的例子. 2.字符串 (1)使用单引号(') (2)使用双引号(") (3)使用三引号('''或"&q

Lua脚本语言简明入门教程

这几天系统地学习了一下Lua这个脚本语言,Lua脚本是一个很轻量级的脚本,也是号称性能最高的脚本,用在很多需要性能的地方,比如:游戏脚本,nginx,wireshark的脚本,当你把他的源码下下来编译后,你会发现解释器居然不到200k,这是多么地变态啊(/bin/sh都要1M,MacOS平台),而且能和C语言非常好的互动.我很好奇得浏览了一下Lua解释器的源码,这可能是我看过最干净的C的源码了. 我不想写一篇大而全的语言手册,一方面是因为已经有了(见本文后面的链接),重要的原因是,因为大篇幅的文

JavaScript入门教程之引用类型

引用类型 引用类型是一种数据结构,用于将数据和功能组织在一起.它也常被称为类,但这种称呼并不妥当.尽管 ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构.引用类型有时候也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法. 前面提到过,引用类型的值便是对象,在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,而对象则是某个特定引用类型的实例. var a=new Object(); 上面便声明了一个引用类

Apache Ant自动化脚本入门教程及常用命令介绍

一 Ant简介 Apache Ant是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的自动化构建.它是Apache软件基金会JAKARTA目录中的一个子项目,它有以下的优点: 跨平台性.Ant是纯Java语言编写的,所以具有很好的跨平台性 操作简单.Ant是由一个内置任务和可选任务组成的.Ant运行时需要一个XML文件(构建文件). Ant通过调用target树,就可以执行各种任务.由于Ant构建文件 是XML格式的文件,所以很容易维护和书写,而且结构清晰

PHP入门教程之正则表达式基本用法实例详解(正则匹配,搜索,分割等)

本文实例讲述了PHP正则表达式基本用法.分享给大家供大家参考,具体如下: Demo1.php <?php //尝试着写第一个正则表达式 //第一个参数,表示模式(就是和字符串去比较,匹配) //第二个参数,表示字符串 //如果整个函数模式和字符串比较后匹配了,那么返回真(true)1,否则返回假(false)0 //什么叫匹配,就是一个一个的比较过去 //按照什么规则??按照模式来匹配 //只要模式全部通过,那么就通过 //匹配和相等是两个概念 //因为目前的模式是一个整体,php //所以,字

PHP入门教程之表单与验证实例详解

本文实例讲述了PHP表单与验证.分享给大家供大家参考,具体如下: Demo1.php <?php ob_start(); //重新导向一个 URL //header() //header('Location:Demo2.php'); //上面这句话可以自动跳转到你所想要的页面. //header('Location:http://www.baidu.com'); //上面这句话自动跳转到百度上面去. echo 'baidu.com'; header('Location:http://www.ba

PHP入门教程之上传文件实例详解

本文实例讲述了PHP上传文件的方法.分享给大家供大家参考,具体如下: Demo1.php <form enctype="multipart/form-data" action="Demo2.php" method="post"> <input type="hidden" name="MAX_FILE_SIZE" value="2000000" /> 上传文件: &

PHP入门教程之面向对象基本概念实例分析

本文实例讲述了PHP面向对象基本概念.分享给大家供大家参考,具体如下: Demo1.php <?php //怎样去创建一个类 格式:修饰符 class 类名{} //我们去创建一个电脑的类,这类可以创建出对象(生产出电脑) class Computer { //类名第一个字母大写 } //创建一台电脑出来,也就是对象的声明 //格式:变量 = new 类名(); //new Compuer() 表示实例化的过程(意思是创建一个对象) //$compuer1 = new Compuer() 这个过

JavaScript模块模式实例详解

本文实例讲述了JavaScript模块模式.分享给大家供大家参考,具体如下: 在JS中没有Class的概念,那么如何体现Object的Public和Private属性呢,答案就是模块模式(Module Pattern). JS中有一个显著的特性: 匿名函数(anonymous function),通过匿名函数的建立和执行,匿名函数里的代码就形成了一个闭包(closure),从而形成,封装和控制一个对象的Private和Public的特性,避免了全局变量的泛滥和与其他脚本的冲突. (functio