WebSocket使用:整合Spring实现消息推送

1 添加依赖:

    <!-- WebSocket -->
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-websocket</artifactId>
         <version>${spring.version}</version>
      </dependency>

      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-messaging</artifactId>
         <version>${spring.version}</version>
      </dependency>

2 创建WebSocketHandler,用于处理WebSocket连接请求:

    public class MessageHandler implements WebSocketHandler{

    private static final Map<String, WebSocketSession> users;//标识用户连接

    private static final String USER_KEY = "current_user";

    static {
        users = new ConcurrentHashMap<String,WebSocketSession>();
    }

    //关闭websocket连接时调用
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        String userId = getUserId(session);
        if(userId != null) {
            users.remove(userId);
        }
    }

    //建立websocket连接时调用
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String userId = getUserId(session);
        if(userId != null) {
            users.put(userId, session);
            session.sendMessage(new TextMessage("建立Socket连接成功!"));
        }
    }

    //客户端调用websocket.send时候,会调用该方法
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        WebSocketMessage message2  = new TextMessage("服务端接收到了您的消息:"+message);
        session.sendMessage(message2);
    }

    //传输异常时
    @Override
    public void handleTransportError(WebSocketSession arg0, Throwable arg1) throws Exception {

    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    //发送消息给特定用户
    public void sendMessageToUser(String userId,String contents) {
        WebSocketSession session = users.get(userId);
        TextMessage message = new TextMessage(contents);
        if(session !=null && session.isOpen()) {
            try {
                session.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //发送消息给所有用户
    public void sendMessageToAllUsers(String contents) {
        Set<String> userIds = users.keySet();
        for(String userId: userIds) {
            this.sendMessageToUser(userId, contents);
        }
    }

    private String getUserId(WebSocketSession session) {
        try {
            String userId = (String)session.
                getAttributes().get(USER_KEY);
            return userId;
        }catch(Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

3 添加HttpSessionHandshakeInterceptor,执行WebSocketHandler前拦截:

    public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {

    private static final String USER_KEY = "current_user";

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Exception e) {
        super.afterHandshake(request, response, handler, e);
    }

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
            Map<String, Object> attrs) throws Exception {

        if(request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)request;
            //获取参数
        String user = serverHttpRequest .getServletRequest().getParameter("user");
        //System.out.println("获取到的User:"+user);
            attrs.put(USER_KEY, user);
        }
        return true;
    }

}

4 配置WebSocket:
方式一:xml配置

<!-- websocket处理类 -->
    <bean id="myHandler" class="websocket.handler.MessageHandler"/> 

    <!-- 握手接口/拦截器 -->
    <bean id="myInterceptor" class="websocket.interceptor.WebSocketInterceptor"/>

    <websocket:handlers >
        <websocket:mapping path="/myHandler" handler="myHandler"/>
        <websocket:handshake-interceptors>
            <ref bean="myInterceptor"/>
        </websocket:handshake-interceptors>
    </websocket:handlers> 

    <!--  注册 sockJS -->
    <websocket:handlers>
        <websocket:mapping path="/sockjs/myHandler" handler="myHandler"/>
        <websocket:handshake-interceptors>
            <ref bean="myInterceptor"/>
        </websocket:handshake-interceptors>
        <websocket:sockjs />
    </websocket:handlers>  

方法二:java代码

package websocket.config;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer{

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(),"/myHandler" ).
            addInterceptors(new WebSocketInterceptor());
        registry.addHandler(myHandler(),"/sockjs/myHandler" ).
            addInterceptors(new WebSocketInterceptor()).withSockJS();
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MessageHandler();
    }
}

同时,spring配置文件添加:

<context:component-scan base-package="websocket.config"/>

5 服务端主动发送消息给客户端:

    @Autowired
    private MessageHandler messageHandler;


    /*
        //发送消息给特定用户
        messageHandler.sendMessageToUser("xxxx");
        //改善消息给所有用户
        messageHandler.sendMessageToAllUsers("xxxxx");
    */

6 前端代码:传递带userid参数请求

    var websocket;

   // 首先判断是否 支持 WebSocket
    if('WebSocket' in window) {
        websocket = new WebSocket("ws://localhost:8080/WebSocket-Start/myHandler?user=minghai");
    } else if('MozWebSocket' in window) {
        websocket = new MozWebSocket("ws://localhost:8080/WebSocket-Start/myHandler?user=minghai");
    } else {
        websocket = new SockJS("http://localhost:8080/WebSocket-Start/sockjs/myHandler?user=minghai");
    }

    // 打开连接时
    websocket.onopen = function(evnt) {
        console.log("  websocket.onopen  ");
    };

    // 收到消息时
    websocket.onmessage = function(evnt) {
        alert(evnt.data);
    };

    websocket.onerror = function(evnt) {
        console.log("  websocket.onerror  ");
    };

    websocket.onclose = function(evnt) {
        console.log("  websocket.onclose  ");
    };

    //客户端主动发消息
    websocket.send("");

猜你喜欢

转载自blog.csdn.net/crazylai1996/article/details/79210659