Java搭建WebSocket的两种方式 (2)

Java搭建WebSocket的两种方式

maven依赖如下:

maven依赖如下:

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-websocket</artifactId>

    <version>2.0.4.RELEASE</version>

</dependency>

1、控制类

package com.boot.river.websocket;

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.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.socket.TextMessage;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;

@Controller

@RequestMapping(value = "/websocket", method = {RequestMethod.POST, RequestMethod.GET})/*GET请求开放用于测试,最好只允许POST请求*/

public class WebSocketController {

    @Autowired

    SpringWebSocketHandler springWebSocketHandler;

    /**

     * 登录将username放入session中,然后在拦截器HandshakeInterceptor中取出

     */

    @ResponseBody

    @RequestMapping("/login")

    public String login(HttpServletRequest request, @RequestParam(value = "username") String username, @RequestParam(value = "password") String password) {

        System.out.println("登录:" + username + ":" + password);

        HttpSession session = request.getSession();

        if (null != session) {

            session.setAttribute("SESSION_USERNAME", username);

            return "success";

        } else {

            return "fail";

        }

    }

    /**

     * 指定发送

     */

    @ResponseBody

    @RequestMapping("/sendToUser")

    public String send(@RequestParam(value = "username") String username, @RequestParam(value = "info") String info) {

        springWebSocketHandler.sendMessageToUser(username, new TextMessage(info));

        System.out.println("发送至:" + username);

        return "success";

    }

    /**

     * 广播

     */

    @ResponseBody

    @RequestMapping("/broadcast")

    public String broadcast(@RequestParam(value = "info") String info) {

        springWebSocketHandler.sendMessageToUsers(new TextMessage("广播消息:" + info));

        System.out.println("广播成功");

        return "success";

    }

}

2、配置类(实现WebSocketConfigurer接口 )

 

@Configuration

@EnableWebSocket

public class SpringWebSocketConfig implements WebSocketConfigurer {

    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

        registry.addHandler(getSpringWebSocketHandler(), "/websocket/server")

                .addInterceptors(getInterceptor()).setAllowedOrigins("*");

        registry.addHandler(getSpringWebSocketHandler(), "/sockjs/server").setAllowedOrigins("*")

                .addInterceptors(getInterceptor()).withSockJS();

    }

    @Bean

    public SpringWebSocketHandler getSpringWebSocketHandler() {

        return new SpringWebSocketHandler();

    }

    @Bean

    public SpringWebSocketHandlerInterceptor getInterceptor() {

        return new SpringWebSocketHandlerInterceptor();

    }

}

3、处理类(实现了WebSocketHandler接口)

package com.boot.river.websocket;

import org.springframework.web.socket.CloseStatus;

import org.springframework.web.socket.TextMessage;

import org.springframework.web.socket.WebSocketSession;

import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

public class SpringWebSocketHandler extends TextWebSocketHandler {

    /**

     * 存储用户id和其对应的session

     */

    private static final Map<String, WebSocketSession> users = new HashMap<>();

    /**

     * 用户名key值

     */

    private static final String USER_ID = "WEBSOCKET_USERID";

    /**

     * 连接建立后触发

     */

    @Override

    public void afterConnectionEstablished(WebSocketSession session) {

        System.out.println("成功建立websocket连接!");

        String userId = (String) session.getAttributes().get(USER_ID);//取出在拦截器中存储的username

        users.put(userId, session);

        System.out.println("当前线上用户数量:" + users.size());

    }

    /**

     * 关闭连接时触发

     */

    @Override

    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {

        String userId = (String) session.getAttributes().get(USER_ID);

        System.out.println("用户" + userId + "已退出!");

        users.remove(userId);

        System.out.println("剩余在线用户" + users.size());

    }

    /**

     * 接收消息

     */

    @Override

    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

        super.handleTextMessage(session, message);

        System.out.println("收到消息:" + message);

        if (message.getPayload().contains("在吗")) {

           session.sendMessage(new TextMessage("对方不在线!"));

        }

    }

    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

        if (session.isOpen()) {

            session.close();

        }

        System.out.println("传输出现异常,关闭websocket连接... ");

        String userId = (String) session.getAttributes().get(USER_ID);

        users.remove(userId);

    }

    public boolean supportsPartialMessages() {

        return false;

    }

    /**

     * 给某个用户发送消息

     */

    public void sendMessageToUser(String userId, TextMessage message) {

        for (String id : users.keySet()) {

            if (id.equals(userId)) {

                try {

                    if (users.get(id).isOpen()) {

                        users.get(id).sendMessage(message);

                    }

                } catch (IOException e) {

                    e.printStackTrace();

                }

                break;

            }

        }

    }

    /**

     * 给所有在线用户发送消息

     */

    public void sendMessageToUsers(TextMessage message) {

        for (String userId : users.keySet()) {

            try {

                if (users.get(userId).isOpen()) {

                    users.get(userId).sendMessage(message);

                }

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

    }

}

4、拦截器(实现HandshakeInterceptor接口)

package com.boot.river.websocket;

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;

public class SpringWebSocketHandlerInterceptor extends HttpSessionHandshakeInterceptor {

    @Override

    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxjzf.html