springMVC+websocket实现消息推送

1.所需jar包 


javax.servlet-api-3.1.0
javax.websocket-api-1.1
spring-messaging-4.0.9.RELEASE
spring-websocket-4.0.9.RELEASE
需要js:
sockjs.min.js
jar包注意和spring版本号一致

2.web.xml配置 



	
	
	
	  contextConfigLocation
	  
	  classpath:applicationContext.xml
	  
	
	
	
    log4jConfigLocation
    classpath:log4j.properties
  
	
    org.springframework.web.util.Log4jConfigListener
  
	
	
	  
	  org.springframework.web.context.ContextLoaderListener
	  
	
	
	
	
	  springmvc
	  org.springframework.web.servlet.DispatcherServlet
	   
	    contextConfigLocation
	    classpath:springmvc.xml
	  
	  2
		true
	
	
	
	
	  springmvc
	  /
	

WebSocket 需要Servlet3.0 需要web.xml 3.0及以上,并要配置此
   
将所有的filter和servlet都要添加异步
    true
 

3.信息处理类 

package com.xwj.websocket;

import com.xwj.entity.People;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description TODO
 * @Author yuki
 * @Date 2018/9/10 9:37
 * @Version 1.0
 **/
@Component
public class MsgScoketHandle implements WebSocketHandler {
    /**已经连接的用户*/
    private static final List peoples;
    static {
        //保存当前连接用户
        peoples = new ArrayList<>();
    }
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        //将用户信息添加到list中
        peoples.add(webSocketSession);
        System.out.println("=====================建立连接成功==========================");
        People people  = (People) webSocketSession.getAttributes().get("people");
        if(people != null){
            System.out.println("当前连接用户======"+people.getUserName());
        }
        System.out.println("webSocket连接数量====="+peoples.size());
    }
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage webSocketMessage) throws Exception {
        People people = (People) webSocketSession.getAttributes().get("people");
        System.out.println("收到用户:"+people.getUserName()+"的消息");
    }
    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
        if (webSocketSession.isOpen()){
            //关闭session
            try {
                webSocketSession.close();
            } catch (IOException e) {
            }
        }
        //移除用户
        peoples.remove(webSocketSession);
    }
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        peoples.remove(webSocketSession);
        People people = (People) webSocketSession.getAttributes().get("people");
        System.out.println(people.getUserName()+"断开连接");
    }
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
    public void sendMessageToUser(People people, TextMessage messageInfo){
        for (WebSocketSession session : peoples) {
            People sessionUser = (People) session.getAttributes().get("people");
            //根据用户名去判断用户接收消息的用户
            if(people.getUserName().equals(sessionUser.getUserName())){
                try {
                    if (session.isOpen()){
                        session.sendMessage(messageInfo);
                        System.out.println("发送消息给:"+people.getUserName()+"内容:"+messageInfo);
                    }
                    break;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public void sendMsgToAllUsers(TextMessage messageInfo) throws Exception{
        for (WebSocketSession user : peoples) {
            user.sendMessage(messageInfo);
        }
    }
}

因为有注解,所以要在springmvc中配置scan 

4.拦截器 

package com.xwj.websocket;

import com.xwj.entity.People;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * @Description TODO
 * @Author yuki
 * @Date 2018/9/10 9:30
 * @Version 1.0
 **/
public class WebSocketHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map map) throws Exception {
        if (request instanceof ServletServerHttpRequest){
            ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) request;
            HttpSession session = servletServerHttpRequest.getServletRequest().getSession(false);
            if(session != null){
                //从session中获取当前用户
                People people = (People) session.getAttribute("people");
                map.put("people",people);
            }
        }
        return true;
    }
    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
        super.afterHandshake(serverHttpRequest,serverHttpResponse,webSocketHandler,e);
    }
}

5.注册配置文件,运用注解方式(也可以在springmvc配置文件中注册) 

package com.xwj.websocket;

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;

/**
 * @Description TODO
 * @Author yuki
 * @Date 2018/9/10 9:20
 * @Version 1.0
 **/
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        System.out.println("===========================注册websocket================");
        webSocketHandlerRegistry.addHandler(msgSocketHandle(),"/websocket")
                .addInterceptors(new WebSocketHandshakeInterceptor());
        webSocketHandlerRegistry.addHandler(msgSocketHandle(),
                "/sockjs/websocket").
                addInterceptors(new WebSocketHandshakeInterceptor())
                .withSockJS();
    }
    @Bean(name = "msgSocketHandle")
    public WebSocketHandler msgSocketHandle(){
        return new MsgScoketHandle();
    }
}

因为有注解,所以要在springmvc中配置scan

6.jsp页面 

<%--
  该页面用于登录,将用户存于session
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

  
    测试websocket
  
  
  
<%--
  该页面用于消息推送
--%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>


    测试requestbody




当前登录用户:${pageContext.session.getAttribute("people").userName}

7.controller

package com.xwj.websocket;

import com.xwj.entity.People;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.socket.TextMessage;
import javax.servlet.http.HttpServletRequest;


@RequestMapping("/websocket")
@Controller
public class MsgController {
    @Autowired
    private MsgScoketHandle msgScoketHandle;
    @RequestMapping("/login")
    public String login(People people, HttpServletRequest request){
        request.getSession().setAttribute("people",people);
        return "socket";
    }
    @ResponseBody
    @RequestMapping(value = "/sendMsg",produces = "application/json; charset=utf-8")
    public String sendMsgToUser(String content,String toUserName){
        People people = new People();
        people.setUserName(toUserName);
        TextMessage textMessage = new TextMessage(content);
        msgScoketHandle.sendMessageToUser(people,textMessage);
        return "发送成功";
    }
    @ResponseBody
    @RequestMapping(value = "/sendMsg2",produces = "application/json; charset=utf-8")
    public String sendMsgToAll(String content) throws Exception {
        TextMessage textMessage = new TextMessage(content);
        msgScoketHandle.sendMsgToAllUsers(textMessage);
        return "发送成功";
    }
}

 

 

 

 

你可能感兴趣的:(开源框架)