Spring+WebSocket+SockJS实现实时聊天

设计初衷是通过websocket实现网页实时通讯聊天。

工程环境:tomcat8+jdk1.7+maven+eclipse

设计思路:客户端登录网页建立socket连接,后台记录用户连接信息并做标识;当用户在网页端发送聊天消息至后台,后台收到信息后将消息发送至接收者,同时后端对消息进行持久保存。


简要代码实现demo如下:

1、pom.xml主要配置

        
            javax.websocket
            javax.websocket-api
            1.0
            provided
        
        
            org.springframework
            spring-websocket
            ${spring.version}
        
        
            org.springframework
            spring-messaging
            ${spring.version}
        
        
            org.springframework
            spring-aop
            ${spring.version}
        
        
            org.apache.logging.log4j
            log4j-api
            ${log4j.version}
        
        
            org.apache.logging.log4j
            log4j-core
            ${log4j.version}
        


        
        
        
            org.springframework
            spring-aspects
            ${spring.version}
        

2、spring核心配置信息

 
                
    
    
                
    
    

3、websocket服务端实现

package com.milanosoft.RCS.web.webSocket.config;

import com.milanosoft.RCS.web.webSocket.hndler.SystemWebSocketHandler;
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;

import com.milanosoft.RCS.web.webSocket.interceptor.HandshakeInterceptor;
import org.springframework.context.annotation.Bean;

@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").addInterceptors(new HandshakeInterceptor())
                .withSockJS();

    }

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

}

4、websocket连接前后的事件类

package com.milanosoft.RCS.web.webSocket.interceptor;

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 attributes) throws Exception {
		
		//解决The extension [x-webkit-deflate-frame] is not supported问题
		if(request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
			request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
        }
		
		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);
	}

}


//解决The extension [x-webkit-deflate-frame] is not supported问题
        if(request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
            request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
        }

其中标红色的代码是为了解决下面的错误,可能是ios手机safari浏览器版本问题引起的。

org.springframework.web.socket.server.HandshakeFailureException: Uncaught failure for request http://localhost:8080/spring4/myHandler; nested exception is java.lang.IllegalArgumentException: The extension [x-webkit-deflate-frame] is not supported


5、websocket消息处理类

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.milanosoft.RCS.web.webSocket.hndler;

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 lzk
 */
@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");
        System.out.println(wss.getHandshakeHeaders().getFirst("Cookie"));
		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、客户端页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>



<%session.setAttribute("user", "lzk"); %>
WebSocket/SockJS Echo Sample (Adapted from Tomcat's echo sample)
    

    

    






这个例子也是在别人的代码基础上进行了一些修改,修复了一些BUG。

想要完整demo的朋友可以点这里下载


你可能感兴趣的:(html5,websocket,Spring)