spring mvc cxf客户端mvc websocket处理客户端消息的回调函数有哪些

&&spring websocket和html5 websocket的完美整合demoWebSocketAppConfig&WebSocketHandshakeInterceptor &握手&&html5 websocket2个牛币请下载代码后再发表评论//target/target/classes/target/classes/application.properties/target/classes/com/target/classes/com/utouu/target/classes/com/utouu/ecs/target/classes/com/utouu/ecs/UtouuECSServerApplication.class/target/classes/com/utouu/ecs/web/target/classes/com/utouu/ecs/web/config/target/classes/com/utouu/ecs/web/config/ErrorPageConfig$MyCustomizer.class/target/classes/com/utouu/ecs/web/config/ErrorPageConfig.class/target/classes/com/utouu/ecs/web/config/SpringMvcConfig.class/target/classes/com/utouu/ecs/web/config/WebSocketAppConfig.class/target/classes/com/utouu/ecs/web/constans/target/classes/com/utouu/ecs/web/constans/WebsocketConstans.class/target/classes/com/utouu/ecs/web/constans/WebsocketType.class/target/classes/com/utouu/ecs/web/controller/target/classes/com/utouu/ecs/web/controller/CaptureAPIController.class/target/classes/com/utouu/ecs/web/controller/CoordinationController.class精精精原精精原原原最热搜索分享话题编程语言基础Web开发数据库开发客户端开发脚本工具游戏开发服务器软硬件开源组件类库相关分享精最近下载暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级最近浏览暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级暂无贡献等级扫描二维码关注最代码为好友"/>扫描二维码关注最代码为好友一、WebSocket简介
WebSocket& protocol是HTML5一种新的协议,WebSocket 是目前唯一真正实现全双工通信的服务器向客户端推送的互联网技术。WebSocket的出现使得浏览器提供对Socket的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道。
HTML5 WebSocket 设计出来的目的就是要取代轮询和 Comet 技术,使客户端浏览器具备像 C/S 架构下桌面系统的实时通讯能力。 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。因为 WebSocket 连接本质上就是一个 TCP 连接,所以在数据传输的稳定性和数据传输量的大小方面,和轮询以及 Comet 技术比较,具有很大的性能优势。
二、WebSocket出现之前实时web应用
Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种 机制对于信息变化不是特别频繁的应用尚能相安无事,但是对于那些实时要求比较高的应用来说,比如说在线游戏、在线证券、设备监控、新闻在线播报、RSS 订阅推送等等,当客户端浏览器准备呈现这些信息的时候,这些信息在服务器端可能已经过时了。所以保持客户端和服务器端的信息同步是实时 Web 应用的关键要素,对 Web 开发人员来说也是一个难题。在 WebSocket 规范出来之前,开发人员想实现这些实时的 Web 应用,不得不采用一些折衷的方案,其中最常用的就是轮询 (Polling) 和 Comet 技术,而 Comet 技术实际上是轮询技术的改进,又可细分为两种实现方式,一种是长轮询机制,一种称为流技术
这是最早的一种实现实时 Web 应用的方案。客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步。这种同步方案的最大问题是,当客户端以固定频率向 服务器发起请求的时候,服务器端的数据可能并没有更新,这样会带来很多无谓的网络传输,所以这是一种非常低效的实时方案。
长轮询是对定时轮询的改进和提高,目地是为了降低无效的网络传输。当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者时间过期,通过这种机制来减少无效的客户端和服务器间的交互。当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提高。
流技术方案通常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户 端和服务器端的连接不过期。通过这种机制可以将服务器端的信息源源不断地推向客户端。这种机制在用户体验上有一点问题,需要针对不同的浏览器设计不同的方 案来改进用户体验,同时这种机制在并发比较大的情况下,对服务器端的资源是一个极大的考验。
综合这几种方案,您会发现这些目前我们所使用的 所谓的实时技术并不是真正的实时技术,它们只是在用 Ajax 方式来模拟实时的效果,在每次客户端和服务器端交互的时候都是一次 HTTP 的请求和应答的过程,而每一次的 HTTP 请求和应答都带有完整的 HTTP 头信息,这就增加了每次传输的数据量,而且这些方案中客户端和服务器端的编程实现都比较复杂,在实际的应用中,为了模拟比较真实的实时效果,开发人员往往 需要构造两个 HTTP 连接来模拟客户端和服务器之间的双向通讯,一个连接用来处理客户端到服务器端的数据传输,一个连接用来处理服务器端到客户端的数据传输,这不可避免地增加了编程实现的复杂度,也增加了服务器端的负载,制约了应用系统的扩展性。
三、WebSocket规范
WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息&Upgrade: WebSocket&表 明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。
客户端到服务端:
GET /demo HTTP/1.1
Connection: Upgrade
Sec-WebSocket-Key2:
Upgrade: WebSocket
Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5
[8-byte security key]
服务端到客户端:
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin:
WebSocket-Location: ws:///demo
[16-byte hash response]
&&&&&&&& &Upgrade:WebSocket&表示这是一个特殊的 HTTP 请求,请求的目的就是要将客户端和服务器端的通讯协议从 HTTP 协议升级到 WebSocket 协议。从客户端到服务器端请求的信息里包含有&Sec-WebSocket-Key1&、&Sec-WebSocket-Key2&和&[8-byte securitykey]&这样的头信息。这是客户端浏览器需要向服务器端提供的握手信息,服务器端解析这些头信息,并在握手的过程中依据这些信息生成一 个 16 位的安全密钥并返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接。一旦连接建立,客户端和服务器端就可以通过这个通道双向传输数据了。
/developerworks/cn/web/1112_huangxa_websocket/
四、Websocket实现:
Tomcat7.0.5以后开始支持websocket。下面根据tomcat7.0.63+jdk1.7.0.79构建了一个小例子
(必须配置jdk环境变量)
第一种方式,继承org.apache.catalina.WebSocketServlet,该方法在tomcat7.0.63中已过时。
这种方式没有做demo,可以参考下面这篇文章
/web/a/8.shtml
第二种方式:注解方式实现
&script type="text/javascript"&
var socket = null;
$(function(){
//建立websocket连接
socket = new WebSocket("ws://"+window.location.host+"${pageContext.request.contextPath}/mySocket");
//打开websocket时触发
socket.onopen = function(){
$("#showMsg").append("连接成功..&br/&");
console.log("websocket open");
//服务端有消息推送到客户端时触发
socket.onmessage = function(message){
console.log(message.data);
var dataJson = JSON.parse(message.data);
//websocket关闭时触发
socket.onclose = function(event){
console.log("websocket close");
//websocket出错时触发
socket.onerror = function(event){
socket.close();
console.log("websocket error");
$("#sendButton").click(function(){
//通过websocket对象的send方法发送数据到服务端,该方法不能直接传送json对象,//可以先将json对象转换成json格式字符串发送给服务端
var obj = {
message:&客户端发送消息,
//或者使用JSON.stringify(obj);如果js报错找不到该方法,可以自定义一个简单的//jquery插件,功能就是将简单json对象转换成json格式字符串
socket.send(obj.toJSONString());
//socket.send($.simpleJsonToString(obj));
&/script"&
$.extend({
simpleJsonToString : function(jsonObj){
var jsonStr = &&;
for(var I in jsonObj){
jsonStr = jsonStr+i+&:&&+jsonObj[i]+&&&;
jsonStr = jsonStr.substring(0,jsonStr.length-1);
jsonStr = jsonStr+&}&;
return jsonS
package com.h3c.
import java.io.IOE
import java.util.HashM
import java.util.M
import java.util.S
import javax.servlet.http.HttpS
import javax.websocket.CloseR
import javax.websocket.EndpointC
import javax.websocket.OnC
import javax.websocket.OnE
import javax.websocket.OnM
import javax.websocket.OnO
import javax.websocket.S
import javax.websocket.server.ServerE
import com.google.gson.G
import net.sf.json.JSONO
//value为访问websocket的路径,configurator为websocket初始化配//置器
@ServerEndpoint(value="/mySocket",configurator=HttpSessionConfigurator.class)
public class MySocket {
static Map&String,Session& sessionMap = new HashMap&String, Session&();
private HttpSession httpS
public void onOpen(Session session,EndpointConfig config){
System.out.println("websocket open");
this.httpSession = (HttpSession) config.getUserProperties().get("httpSession");
sessionMap.put((String) httpSession.getAttribute("userAccount"),session);
@OnMessage
public void onMessage(String msg,Session session) throws IOException{
//将客户端发送的json格式字符串转换成实体对象,客户端徐传送json格式数据
//需要jar包:json-lib-2.4-jdk15.jar
JSONObject jsonObject = JSONObject.fromObject(msg);
transferClassMessage transfer = (transferClassMessage)
jsonObject.toBean(jsonObject, transferClassMessage.class);
Gson gson = new Gson();
Set&Map.Entry&String, Session&& set = sessionMap.entrySet();
for(Map.Entry&String,Session& sessionEntry:set){
//向指定客户端发送消息
if("fw1778".equals(sessionEntry.getKey())){
sessionEntry.getValue().getBasicRemote().sendText(gson.toJson("服务端返回消息"));
public void onClose(Session session,CloseReason closeReason){
sessionMap.remove(session.getId());
System.out.println("websocket close");
public void error(Session session,Throwable ta){
sessionMap.remove(session.getId());
System.out.println(ta);
Websocket通过javax.websocket.Session向客户端发送数据,
package com.h3c.
import javax.servlet.http.HttpS
import javax.websocket.HandshakeR
import javax.websocket.server.HandshakeR
import javax.websocket.server.ServerEndpointC
public class HttpSessionConfigurator extends ServerEndpointConfig.Configurator{
public void modifyHandshake(ServerEndpointConfig config,
HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession = (HttpSession)request.getHttpSession();
if(null!=httpSession){
config.getUserProperties().put("httpSession", httpSession);
四、Websocket与spring整合(spring版本为4.0或者以上)
第一种,配置方式。
第二种:注解方式
Spring相关配置文件(略) spring配置出错,可能会出现handshake的错误,切勿忘记配置spring的自动扫描:&context:component-scan base-package="com.h3c.itac" /&
Spring websocket配置类
package com.h3c.itac.
import org.springframework.context.annotation.C
import org.springframework.web.servlet.config.annotation.EnableWebM
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerA
import org.springframework.web.socket.config.annotation.EnableWebS
import org.springframework.web.socket.config.annotation.WebSocketC
import org.springframework.web.socket.config.annotation.WebSocketHandlerR
* spring websocket配置类,在tomcat启动时会调用该类注册websockethandlers的方法注册handler
* @author lfw1950
@Configuration
@EnableWebMvc
@EnableWebSocket
public class TranferWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{
//注册handler,可以注册多个handler
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
* addHandler方法第一个参数为处理websocket的handler,第二个参数为访问路径,addInterceptors方法徐传入一个handshake拦截器
* 该拦截器会在建立wensocket连接之前执行
registry.addHandler(new TransferWebSocketHandler(), "/transfer").addInterceptors(new TransferHandshakeInterceptor());
Spring websocket拦截器
package com.h3c.itac.
import java.util.M
import javax.servlet.http.HttpS
import org.springframework.http.server.ServerHttpR
import org.springframework.http.server.ServerHttpR
import org.springframework.http.server.ServletServerHttpR
import org.springframework.web.socket.WebSocketH
import org.springframework.web.socket.server.HandshakeI
public class TransferHandshakeInterceptor implements HandshakeInterceptor{
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler handler, Exception e) {
System.out.println("after handshake");
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler handler,
Map&String, Object& attr) throws Exception {
System.out.println("before handshake");
if(request instanceof ServletServerHttpRequest){
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest)
HttpSession httpSession = servletRequest.getServletRequest().getSession();
if(null!=httpSession){
String userName = (String) httpSession.getAttribute("userAccount");
* map中存放的数据可以通过session.getAttributes().get(key)获取
* 如:session.getAttributes().get("wsUserAccount")
attr.put("wsUserAccount", userName);
* 默认为false,要修改为true,否则无法建立websocket连接
* WebSocket connection to 'ws://localhost:8888/ITAC_Cloud/transfer' failed: Error during WebSocket handshake: Unexpected response code: 200
return true;
Spring websocket处理器
package com.h3c.itac.
import java.util.HashM
import java.util.M
import java.util.S
import org.springframework.web.socket.CloseS
import org.springframework.web.socket.TextM
import org.springframework.web.socket.WebSocketH
import org.springframework.web.socket.WebSocketM
import org.springframework.web.socket.WebSocketS
public class TransferWebSocketHandler implements WebSocketHandler{
private Map&String, WebSocketSession& wsSessions = new HashMap&String, WebSocketSession&();
public void afterConnectionClosed(WebSocketSession session, CloseStatus arg1)
throws Exception {
System.out.println("websocket close");
wsSessions.remove(session.getAttributes().get("wsUserAccount"));
* 打开连接时执行
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
System.out.println("websocket open");
wsSessions.put((String) session.getAttributes().get("wsUserAccount"), session);
public void handleMessage(WebSocketSession session, WebSocketMessage&?& message)
throws Exception {
String receiveData = (String) message.getPayload();//从客户端接收到的数据
Set&Map.Entry&String, WebSocketSession&& set = wsSessions.entrySet();
for(Map.Entry&String,WebSocketSession& sessionEntry:set){
* 模拟交接班中被交接的坐席的域账号为fw1950,则只有登陆的账号为fw1950的客户端会收到服务端传送过去的数据
if("fw1950".equals(sessionEntry.getKey())){
sessionEntry.getValue().sendMessage(new TextMessage("服务端返回数据"));
public void handleTransportError(WebSocketSession session, Throwable e)
throws Exception {
System.out.println("websocket error");
wsSessions.put((String) session.getAttributes().get("wsUserAccount"), session);
* 暂时不清楚该方法有什么作用
public boolean supportsPartialMessages() {
return false;
页面和普通的websocket实现基本一样
&%@ page language="java" contentType="text/ charset=UTF-8"
pageEncoding="UTF-8"%&
&!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&
&meta http-equiv="Content-Type" content="text/ charset=UTF-8"&
&title&Insert title here&/title&
&script type="text/javascript" src="${pageContext.request.contextPath }/resources/js/jquery-1.11.2.js "&&/script&
&div id="showMsg" style="border: :1width: 500height: 400overflow:"&&/div&
&input type="text" id="msg"&
&input type="button" id="sendButton" value="send"/&
&div id="toNext" title="接班详情" style="display:"&
&script type="text/javascript"&
var socket = null;
$(function(){
socket = new WebSocket("ws://"+window.location.host+"${pageContext.request.contextPath}/transfer");
socket.onopen = function(){
$("#showMsg").append("连接成功..&br/&");
console.log("websocket open");
socket.onmessage = function(message){
console.log(message.data);
socket.onclose = function(event){
console.log("websocket close");
socket.onerror = function(event){
socket.close();
console.log("websocket error");
$("#sendButton").click(function(){
socket.send("客户端发送消息");
可以参考:
http://my.oschina.net/ldl123292/blog/304360
阅读(...) 评论()博客访问: 2492505
博文数量: 698
博客积分: 10
博客等级: 民兵
技术积分: 11080
注册时间:
认证徽章:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 架构设计与优化
Spring WebSocket详解
Spring框架从4.0版开始支持WebSocket,下面我将详述Spring WebSocket库的相关内容。内容包括Spring框架是如何在Web应用中支持WebSocket方式的消息通信,以及如何利用STOMP协议作为应用层的协议——WebSocket的子协议。
1、WebSocket协议介绍
WebSocket协议是RFC-6455规范定义的一个Web领域的重要的功能:全双工,即客户端和服务器之间的双向通信。它是一个令人兴奋的功能,业界在此领域上已经探索很久,使用的技术包括Java Applet、XMLHttpRequest、Adobe Flash、ActiveXObject、各种Comet技术、服务器端的发送事件等。
需要理解一点,在使用WebSocket协议前,需要先使用HTTP协议用于构建最初的握手。这依赖于一个机制——建立HTTP,请求协议升级(或叫协议转换)。当服务器同意后,它会响应HTTP状态码101,表示同意切换协议。假设通过TCP套接字成功握手,HTTP协议升级请求通过,那么客户端和服务器端都可以彼此互发消息。
Spring框架4.0以上版本引入了一个新模块,即spring-websocket模块。它对WebSocket通信提供了支持。它兼容Java WebSocket API规范JSR-356,同时提供了额外的功能
2、WebSocket的降级选项
浏览器对WebSocket的支持并不快,IE浏览器是第10版才开始支持的。此外,一些代理工具也会限制WebSocket通信。因此,即使是现在要开发WebSocket应用,降级选项是必不可少的,以便在不支持的场景使用模拟WebSocket API的工作方式。Spring框架提供了这种透明的降级方案——使用SockJS协议。此方案可以通过配置来自动切换,无需修改应用程序的代码。
3、消息通信架构
使用WebSocket除了开发方面的挑战外,还有一个难点在于设计上的考虑。
目前REST架构是一个广泛接受、易于理解、适合构建现代Web应用的架构。REST架构依赖于很多URL、和几个HTTP方法,使用了链接、保持无状态等原则。
相比之下WebSocket应用可能只使用一个URL用于最初的HTTP握手。随后所有的消息都共享此TCP连接,消息在此连接上双向流动。这一点可见,它与REST架构是完全不同的,是异步的、事件驱动的、消息传递的架构。WebSocket架构与传统的消息传输方案(如JMS、AMQP)比较相似。
Spring框架4.0引入了一个新模块——spring-messaging模块,它包含了很多来自于Spring Integration项目中的概念抽象,比如:Message消息、消息频道MessageChannel、消息句柄MessageHandler等。此模块还包括了一套注释,可以把消息映射到方法上,与Spring MVC基于注释的编程模型相似。
4、WebSocket支持子协议
WebSocket只是一个消息传递的体系结构,它没有指定任何特定的消息传递协议。它是一个TCP协议之上的超薄层,可以把字节流转换成消息流(文本货二进制)。随后由应用程序来解释消息。
与HTTP协议不同,WebSocket协议只是一个应用级的协议,它非常简单,并不能理解传入的消息,也不能对消息进行路由或处理。因此WebSocket协议是应用级协议的底层,其上需要一个框架来理解和处理消息。
出于这个原因,WebSocket RFC定义了子协议的使用。在握手过程中,客户端和服务器端可以使用Header部分的Sec-WebSocket-Protocol来协商使用的子协议——也即使用更高级的应用级协议。子协议的使用不是必须的,但即使不使用子协议,应用程序仍然需要选择一个消息格式——让客户端和服务器相互可以理解的格式。这种格式可以自定义,或特定于框架,或使用标准的消息传递协议。
Spring框架提供了对使用STOMP子协议的支持。
STOMP,Streaming Text Orientated Message Protocol,流文本定向消息协议。STOMP是一个简单的消息传递协议, 是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。
STOMP提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互,类似于OpenWire协议(一种二进制协议)。
5、什么场景下该使用WebSocket
在Web应用中,客户端和服务器端需要以较高频率和较低延迟来交换事件时,适合用WebSocket。因此WebSocket适合财经、游戏、协作等应用场景。
对于其他应用场景则未必适合。例如,某个新闻订阅需要显示突发新闻,使用间隔几分钟的长轮询也是可以的,这里的延迟可以接受。
即使在要求低延迟的应用场景,如果传输的消息数很低(比如监测网络故障的场景),那么应该考虑使用长轮询技术。
而只有在低延迟和高频消息通信的场景下,选用WebSocket协议才是非常适合的。即使是这样的应用场景,仍然存在是选择WebSocket通信呢?又或者是选择REST HTTP通信呢?
答案是会根据应用程序的需求而定。但是,也可能同时使用这两种技术,把需要频繁交换的数据放到WebSocket中实现,而把REST API作为过程性的业务的实现技术。另外,当REST API的调用中需要把某个信息广播给多个客户端是,也可以通过WebSocket连接来实现。
Spring框架提供了@Controller注释和@RestController注释,两者都可以用于HTTP请求的处理以及WebSocket消息的处理。另外,Spring MVC的请求处理方法,或其它应用程序的请求处理方法,都可以很容易地使用WebSocket协议来广播消息到所有感兴趣的客户端或指定用户。
阅读(9449) | 评论(1) | 转发(2) |
相关热门文章
给主人留下些什么吧!~~
楼主辛苦http://kaopu.so
请登录后评论。2163人阅读
Spring(8)
一、测试环境
Tomcat8.0.18
二、新建一个SpringMVC的工程
使用Maven新建一个web工程,添加SpringMVC和Spring websocket依赖,pom.xml文件如下
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&
&daybreak&
&spring-websocket&
&0.0.1-SNAPSHOT&
&spring-websocket Maven Webapp&
&http://maven.apache.org&
&javax.servlet&
&javax.servlet-api&
&org.springframework&
&spring-webmvc&
&4.1.4.RELEASE&
&com.fasterxml.jackson.core&
&jackson-core&
&com.fasterxml.jackson.core&
&jackson-databind&
&org.springframework&
&spring-websocket&
&4.1.4.RELEASE&
&spring-websocket&
&org.apache.maven.plugins&
&maven-war-plugin&
&src/main/webapp&
修改web.xml文件如下
&?xml version="1.0" encoding="UTF-8"?&
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="/xml/ns/javaee"
xsi:schemaLocation="/xml/ns/javaee /xml/ns/javaee/web-app_3_0.xsd" version="3.0"&
&contextConfigLocation&
&/WEB-INF/applicationContext-*.xml&
&org.springframework.web.context.ContextLoaderListener&
&spring-websocket&
&org.springframework.web.servlet.DispatcherServlet&
&contextConfigLocation&
&/WEB-INF/applicationContext-servlet.xml&
&spring-websocket&
&/index.jsp&
配置springMVC如下applicationContext-servlet.xml
&?xml version="1.0" encoding="UTF-8"?&
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"&
id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/&
class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" &
name="messageConverters"&
bean="mappingJacksonHttpMessageConverter" /&
base-package="cn.com"/&
class="org.springframework.web.servlet.view.InternalResourceViewResolver"&
name="viewClass" value="org.springframework.web.servlet.view.JstlView"/&
name="prefix" value="/view/"/&
name="suffix" value=".jsp"/&
三、配置Spring Websocket
1. 新建一个自己的HandShakeInterceptor类
HandShakeInterceptor是websocket握手拦截器,用于拦截websocket初始化连接的请求
.websocket.
import org.springframework.web.socket.CloseS
import org.springframework.web.socket.TextM
import org.springframework.web.socket.WebSocketM
import org.springframework.web.socket.WebSocketS
import org.springframework.web.socket.handler.TextWebSocketH
public class HelloHandler extends TextWebSocketHandler{
public void handleTextMessage(WebSocketSession session, TextMessage message) {
//接收到客户端消息时调用
System.out.println(“text message: ” + session.getId() + “-” + message.getPayload());
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
// 与客户端完成连接后调用
System.out.println(“afterConnectionEstablished”);
System.out.println(“getId:” + session.getId());
System.out.println(“getLocalAddress:” + session.getLocalAddress().toString());
System.out.println(“getTextMessageSizeLimit:” + session.getTextMessageSizeLimit());
System.out.println(“getUri:” + session.getUri().toString());
System.out.println(“getPrincipal:” + session.getPrincipal());
session.sendMessage(new TextMessage(“你好”.getBytes()));
public void handleTransportError(WebSocketSession session,
Throwable exception) throws Exception {
// 消息传输出错时调用
System.out.println(“handleTransportError”);
public void afterConnectionClosed(WebSocketSession session,
CloseStatus closeStatus) throws Exception {
// 一个客户端连接断开时关闭
System.out.println(“afterConnectionClosed”);
public boolean supportsPartialMessages() {
// TODO Auto-generated method stub
2. 新建一个自己的WebSocketHandler类
WebSocketHandler接口主要是用来与websocket客户端来进行交互的接口,Spring WebSocket提供了一些实现类,可以根据自己的需求进行选择与重写
package cn.com.websocket.
import org.springframework.web.socket.CloseS
import org.springframework.web.socket.TextM
import org.springframework.web.socket.WebSocketM
import org.springframework.web.socket.WebSocketS
import org.springframework.web.socket.handler.TextWebSocketH
public class HelloHandler extends TextWebSocketHandler{
public void handleTextMessage(WebSocketSession session, TextMessage message) {
System.out.println("text message: " + session.getId() + "-" + message.getPayload());
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
System.out.println("afterConnectionEstablished");
System.out.println("getId:" + session.getId());
System.out.println("getLocalAddress:" + session.getLocalAddress().toString());
System.out.println("getTextMessageSizeLimit:" + session.getTextMessageSizeLimit());
System.out.println("getUri:" + session.getUri().toString());
System.out.println("getPrincipal:" + session.getPrincipal());
session.sendMessage(new TextMessage("你好".getBytes()));
public void handleTransportError(WebSocketSession session,
Throwable exception) throws Exception {
System.out.println("handleTransportError");
public void afterConnectionClosed(WebSocketSession session,
CloseStatus closeStatus) throws Exception {
System.out.println("afterConnectionClosed");
public boolean supportsPartialMessages() {
return false;
配置Spring WebSocket
在spring的配置文件 applicationContext-servlet.xml中添加如下配置:
id="HelloHandler" class="cn.com.websocket.hello.HelloHandler"/&
path="/hello" handler="HelloHandler"/&
class="cn.com.websocket.hello.HandShakeInterceptor"/&
class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean"&
name="maxTextMessageBufferSize" value="8192"/&
name="maxBinaryMessageBufferSize" value="8192"/&
注意上述配置中sockjs的开启配置,如果去掉这一配置,则表示不开启sockjs,那么javascript客户端的调用就要采用标准的HTML的WebSocketAPI。开启了sockjs,则要使用sockjs的javascript接口。
部署启动tomcat
将上述的工程编译好后部署在tomcat中,一个websocket服务端就开始运行了
四、WebSocket的js客户端
非sockjs客户端
在上述配置websocket中,如果不加入&websocket:sockjs/&这一配置,那么就采用HTML5的WebSocketAPI来进行通信,需要注意的是必须考虑浏览器是否支持,浏览器的支持情况如下:
示例代码如下:
&!DOCTYPE html&
&WebSocket/SockJS Echo Sample (Adapted from Tomcat's echo sample)&
src="./sockjs.js"&&
type="text/javascript"&
wsServer = 'ws://127.0.0.1:8080/test/hello';
websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) { onOpen(evt) };
websocket.onclose = function (evt) { onClose(evt) };
websocket.onmessage = function (evt) { onMessage(evt) };
websocket.onerror = function (evt) { onError(evt) };
function onOpen(evt) {
console.log("Connected to WebSocket server.");
function onClose(evt) {
console.log("Disconnected");
function onMessage(evt) {
console.log('Retrieved data from server: ' + evt.data);
function onError(evt) {
console.log('Error occured: ' + evt.data);
其中wsServer = ‘ws://127.0.0.1:8080/test/hello’中的地址要根据自己的实际情况来定,一般形式为:ws://域名:端口/应用路径/WebSocket配置的path。“应用路径”是应用部署在tomcat中的文件夹路径,“WebSocket配置的path”是配置文件中&websocket:mapping path="/hello" handler="HelloHandler"/&这条配置项配置的路径。
将这个html页面放入tomcat中运行,在浏览器中访问这个html页面,可以查看浏览器的控制台日志:
WebSocket服务器后台输出入下图:
sockjs客户端
在上述配置websocket中,如果加入这一配置,则表示开启sockjs支持,那么js客户端就必须采用sockjs提供的javascript接口,代码如下:
&!DOCTYPE html&
&title&WebSocket/SockJS Echo Sample (Adapted from Tomcat's echo sample)&/title&
&script src="./sockjs.js"&&/script&
&script type="text/javascript"&
wsServer = 'ws:
websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) { onOpen(evt) };
websocket.onclose = function (evt) { onClose(evt) };
websocket.onmessage = function (evt) { onMessage(evt) };
websocket.onerror = function (evt) { onError(evt) };
function onOpen(evt) {
console.log("Connected to WebSocket server.");
function onClose(evt) {
console.log("Disconnected");
function onMessage(evt) {
console.log('Retrieved data from server: ' + evt.data);
function onError(evt) {
console.log('Error occured: ' + evt.data);
var sock = new SockJS('http://127.0.0.1:8080/test/hello');
sock.onopen = function() {
console.log('open');
sock.send('test');
setTimeout(function(){sock.send('later');},3000);
sock.onmessage = function(e) {
console.log('message', e.data);
sock.onclose = function() {
console.log('close');
注意var sock = new SockJS(‘‘);这里的地址是http地址,与上面的非sockjs不同。
将这个html页面放入tomcat中运行,在浏览器中访问这个html页面,可以查看浏览器的控制台日志:
后台输出为:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6918次
排名:千里之外
原创:16篇
(1)(1)(2)(4)(3)(9)}

我要回帖

更多关于 spring mvc 回调 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信