实现的版本jdk1.7.0_25, tomcat7.0.47.0, Tengine/2.1.1 (nginx/1.6.2), servlet3.0, spring4.2.2   

使用maven导入版本3.0+的servlet包:

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>

然后配置web.xml将版本的xsi配置在3.0以上:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">

导入spring web socket包:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>

在spirng的DispatcherServlet的配置文件配置spring websocket handler,配置了建立连接的路径并通过allowed-origins参数来允许跨域访问:

    <websocket:handlers allowed-origins="*">
<websocket:mapping path="/outer/notice/listen" handler="noticeMessageHandler"/>
<websocket:handshake-interceptors>
<bean class="com.j.socket.notice.NoticeMessageInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers> <websocket:handlers allowed-origins="*">
<websocket:mapping path="/outer/notice/sockjs/listen" handler="noticeMessageHandler"/>
<websocket:handshake-interceptors>
<bean class="com.j.socket.notice.NoticeMessageInterceptor"/>
</websocket:handshake-interceptors>
<websocket:sockjs/>
</websocket:handlers>

配置handler class:

package com.j.socket.notice.NoticeMessageHandler;

// import packages
@Component
public class NoticeMessageHandler implements WebSocketHandler { //存储当前所有的在线用户socket
//目前以userId为key,所以一个用户打开多个socket页面时只会在最新的页面推送消息
private static final Map<String, WebSocketSession> users = new HashMap<>(); //socket 连接常见时该方法被调用
@Override
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
 //在socket Interceptor中设置的参数
String userId = webSocketSession.getAttributes().get("SOCKET_USER");
users.put(userId, webSocketSession);
} @Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
    //前端发送消息时调用该方法
}   //连接出错时
@Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
if (webSocketSession.isOpen()) {
webSocketSession.close();
}
String userId = webSocketSession.getAttributes().get("SOCKET_USER");
users.remove(userId);
}   //连接关闭时
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
String userId = webSocketSession.getAttributes().get("SOCKET_USER");
users.remove(userId);
} @Override
public boolean supportsPartialMessages() {
return false;
}   //向某个用户发送消息
public void sendMessage(TextMessage message, String userId) {
WebSocketSession user = users.get(userId);
if (null != user && user.isOpen()) {
try {
user.sendMessage(message);
} catch (Exception e) {
}
}
}   //批量向所有用户发送消息
public void sendMessage(TextMessage message) {
for (WebSocketSession user : users.values()) {
if (user.isOpen()) {
try {
user.sendMessage(message);
} catch (Exception e) {
}
}
}
}
}

配置拦截器,在websocket链接时从请求中获取用户数据,并存储起来。

public class NoticeMessageInterceptor implements HandshakeInterceptor {

    @Override
public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
if (serverHttpRequest instanceof ServletServerHttpRequest) {
ServletServerHttpRequest request = (ServletServerHttpRequest) serverHttpRequest;
String userId = request.getServletRequest().getParameter("userId");
if (StringUtils.isNotBlank(userId)) {
map.put(Constants.SOCKET_USER, userId);
return true;
}
}
return false;
} @Override
public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { } }

前端js代码,如果浏览器不支持socket时将使用sockJS 所以需要根据情况导入sockJS文件

var websocket;
if ('WebSocket' in window) {
websocket = new WebSocket("ws://yoururl.com/outer/notice/listen?userId="+ getUserId());
} else if ('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://yoururl.com/outer/notice/listen?userId="+getUserId());
} else {
websocket = new SockJS("http://yoururl.com/outer/notice/sockjs/listen?userId="+getUserId());
}
websocket.onopen = function (evnt) {
};
var length = 0 ;
websocket.onmessage = function (evnt) {
console.log(length+=evnt.data.length);
};
websocket.onerror = function (evnt) {
console.log(evnt);
};
websocket.onclose = function (evnt) {
}

nginx相应配置

map $http_upgrade $connection_upgrade {
  default upgrade;
  '' close;
} server {   ... location ~* /(outer/notice)|(outer/sockjs/notice)/ { proxy_pass http://127.0.0.1:8084;
proxy_redirect off; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; }

spring4+websocket+nginx详细配置的更多相关文章

  1. nginx 详细配置

    Nginx全局变量 Nginx中有很多的全局变量,可以通过$变量名来使用.下面列举一些常用的全局变量: 变量 说明 boxClass 需要执行动画的元素的 变量 说明 $args 请求中的参数,如ww ...

  2. Nginx详细配置

    #运行用户#user  nobody; #启动进程,通常设置成和cpu的数量相等或者2倍于cpu的个数(具体结合cpu和内存).默认为1worker_processes  1; #全局的错误日志和日志 ...

  3. 170817、Nginx详细配置

    Nginx能做什么 nginx主要是做转发,当然也可以做静态资源文件缓存,做转发的时候,比如你有几个url,可以统一通过走nginx,然后通过nginx转发到不同的url上 1.反向代理 反向代理应该 ...

  4. CentOS+Nginx+PHP+MySQL详细配置(图解)

    原文地址: http://www.jb51.net/article/26597.htm CentOS+Nginx+PHP+MySQL详细配置(带有图解),需要的朋友可以参考下.   一.安装MySQL ...

  5. Nginx keepalived实现高可用负载均衡详细配置步骤

    Keepalived是一个免费开源的,用C编写的类似于layer3, 4 & 7交换机制软件,具备我们平时说的第3层.第4层和第7层交换机的功能.主要提供loadbalancing(负载均衡) ...

  6. Nginx location配置详细解释

    nginx location配置详细解释 语法规则: location [=|~|~*|^~] /uri/ { - } = 开头表示精确匹配 ^~ 开头表示uri以某个常规字符串开头,理解为匹配 ur ...

  7. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

  8. wordpress nginx详细环境配置安装命令和相关问题解决

    很详细的有关WordPress和nginx的环境配置安装操作步骤 指南,适合新手一步步按照命令操作安装WordPress并运行在生产环境中. 操作步骤转载自: Heap Stack blog(ping ...

  9. [转帖]nginx location配置详细解释

    nginx location配置详细解释 http://outofmemory.cn/code-snippet/742/nginx-location-configuration-xiangxi-exp ...

随机推荐

  1. WPF显示Html

    1.添加引用 WindowsFormsIntegration.dll System.Windows.Forms.dll 2.界面内容 <UserControl x:Class="HKD ...

  2. 9月10日,美团网2014校招研发笔试哈尔滨站 1、链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现

    // reverselink.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" struct Node{ int num; struct No ...

  3. PHP扩展开发及内核应用

    目录中汉字部分代表已经翻译完成的章节,带链接的表示已经发布的,未待链接的表示正在校正即将发布的. PHP的生命周期 让我们从SAPI开始 PHP的启动与终止 PHP的生命周期 线程安全 小结 PHP变 ...

  4. Lunix 命令

    awk '{a[$1]+=1;if(a[$1]==1){print $0}}' awk -F ','  '{print $1, $6}'  IS.csv | sort -k1n -k2n | awk ...

  5. 今天携程出事了:让我们来学习下http的响应码

    就在今天,2015年5月28日,中国最大的旅游机票预订网站--携程网粗大事了.据传携程网的数据库被人物理删除了,而容灾备份的数据又无法正常使用,服务器全面遭受瘫痪.每小时给携程带来的损失约100万美元 ...

  6. Magento-找出没有图片的产品

    最近维护网站,发现网站的产品很多都没有图片显示,看了一下是因为没有在后台勾选图片,就是 image small_image  thumbnail 这三项,就算有图片如果没有勾选的话也不会显示出来,产品 ...

  7. 自定义 JSON 对象

    针对 IE9 以下不支持 JSON 对象的处理方式,网上大部分自定义的方式无形之中都会将中文转码为 Unicode 编码格式的字符换,但是在浏览器中我们有无法察觉到(浏览器自己解析成 UTF8 了), ...

  8. 多Web服务器之间共享Session的解决方案

    一.提出问题: 为了满足足够大的应用,满足更多的客户,于是我们架设了N台Web服务器(N>=2),在多台Web服务器的情况下,我们会涉及到一个问题:用户登陆一台服务器以后,如果在跨越到另一台服务 ...

  9. mysql 主命令总结

    mysql 登录和恢复命令 mysqladmin 管理 mysql 命令 mysqldump 备份命令 mysqlbinlog 解析 binlog 命令 source 恢复数据命令

  10. iOS 消息转发机制

    这篇博客的前置知识点是 OC 的消息传递机制,如果你对此还不了解,请先学习之,再来看这篇.这篇博客我尝试用口语的方式像讲述 PPT 一样给大家讲述这个知识点. 我们来思考一个问题,如果对象在收到无法解 ...