码迷,mamicode.com
首页 > 编程语言 > 详细

Spring Websocket配置

时间:2016-01-14 22:27:40      阅读:322      评论:0      收藏:0      [点我收藏+]

标签:

实现的版本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:

    <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";

}

 

Spring Websocket配置

标签:

原文地址:http://www.cnblogs.com/whataya/p/4929344.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!