java填坑之路

在springBoot框架下利用websocket实现消息推送(

2018-09-20  本文已影响262人  郭小颖在2018

websocket实现消息推送

1、添加Spring WebSocket的依赖jar包

<!-- https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket -->
        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.3.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-messaging -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>4.3.18.RELEASE</version>
        </dependency>

2、建立一个类实现websocketconfigurer接口

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Autowired
    WebSocketUtil webSocketUtil;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketUtil,"/webSocket").addInterceptors(new SpringWebSocketHandlerInterceptor());
        registry.addHandler(webSocketUtil,"/sockJs").addInterceptors(new SpringWebSocketHandlerInterceptor()).withSockJS();
    }
}

3、继承WebSocketHandler对象

@Component
public class WebSocketUtil extends TextWebSocketHandler {
    private Map<String, WebSocketSession> socketCache = new ConcurrentHashMap<>();
    //private static final ArrayList<WebSocketSession> users;//这个会出现性能问题,最好用Map来存储,key用userid
    private static Logger logger = LoggerFactory.getLogger(WebSocketUtil.class);
    /*static {
        users = new ArrayList<WebSocketSession>();
    }*/
    public WebSocketUtil() {
        // TODO Auto-generated constructor stub
    }

    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("connect to the websocket success......当前数量:" + socketCache.size());
        String token = (String) session.getAttributes().get("token");
        System.out.println(token);
        socketCache.put(token, session);
        System.out.println("连接后的数量为:" + socketCache.size());
    }


    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.debug("websocket connection closed......");
        String token = (String) session.getAttributes().get("token");
        System.out.println("用户" + token + "已退出!");
        socketCache.remove(token);
        System.out.println(socketCache.get(token));
        System.out.println("剩余在线用户" + socketCache.size());
    }


    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
    }

    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            session.close();
        }
        logger.debug("websocket connection closed......");
        String token = (String) session.getAttributes().get("token");
        socketCache.remove(token);
    }

    public boolean supportsPartialMessages() {
        return false;
    }


    public boolean send(String token, TextMessage message) {
        if (socketCache.containsKey(token)) {
            return send(socketCache.get(token), message);
        }
        logger.info("socketCache   is  not  key ");
        return false;
    }

    public void sendAll(TextMessage message) {
        if (message == null) return;
        for (WebSocketSession webSocketSession : socketCache.values()) {
            send(webSocketSession, message);
        }
    }

    public boolean send(WebSocketSession webSocketSession, TextMessage message) {
        String token = (String) webSocketSession.getAttributes().get("token");
        if (token==null){
            return false;
        }
        try {
            webSocketSession.sendMessage(message);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("websocket 数据发送异常 !");
            return false;
        }
    }
}

4、继承HttpSessionHandshakeInterceptor对象

/**
 * websocket拦截器
 */
public class SpringWebSocketHandlerInterceptor extends HttpSessionHandshakeInterceptor {
    @Autowired
    UserService userService;

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Map<String, Object> attributes) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("Before Handshake");
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            //1.拿去前段请求中携带的token
            String token = servletRequest.getServletRequest().getParameter("token");
            //2.对token进行判断,如果token不存在,则进行拦截
            if (token==null){
                return false;
            }
            UserInfo userInfo = userService.getloginuserinfo(token);
            if (userInfo==null){
                return false;
            }
            attributes.put("token",token);
           /* if (token!=null){
                UserInfo userInfo = userService.getloginuserinfo(token);
                if (userInfo!=null){
                    attributes.put("token",token);
                }
            }*/
        }
        System.out.println("handshake...");
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                               Exception ex) {
        // TODO Auto-generated method stub
        System.out.println("afterHandshake...");
        super.afterHandshake(request, response, wsHandler, ex);
    }
}

1.定义一个控制器用来做连接标识和发送消息

@RestController
public class MessagePushController {


    @Autowired
    private WebSocketUtil webSocketUtil;

    /**
     * 给某个用户发送消息
     *
     * @param token
     * @param message
     * @return
     */
    @PostMapping("/push")
    public String tokenPush(String token, String message) {
        return  webSocketUtil.send(token,new TextMessage(message))?"success":"fail";
    }

    /**
     * 广播,给所有在线用户发送广播
     *
     * @param message
     * @return
     */
    @PostMapping("/broadcast")
    public String Push(String message) {
        try {
            webSocketUtil.sendAll(new TextMessage(message));
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            return "false";
        }
    }
}

2、建立发消息页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta name="viewport" content="width=device-width" charset="UTF-8"/>
    <title>WebSocket 客户端</title>
</head>

<body>
<div>

    token:<input type="text" id="token"/>
    <input type="button" id="btnConnection" value="连接到服务器"/><br/>
    <input type="text" id="inputMsg"/>
    <input type="button" id="btnSend" value="客户端发送消息" /><br/>
    <input type="button" id="btnClose" value="客户端关闭连接" /><br/>

</div>
<script src="js/jquery-1.8.3.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
    var websocket = null;
    if (typeof(WebSocket) == "undefined") {
        alert("您的浏览器不支持WebSocket");
    }

     //连接到ws服务器
     $("#btnConnection").click(function () {
         var token=document.getElementById("token").value;
         //实现化WebSocket对象,指定要连接的服务器地址与端口
         websocket = new WebSocket("ws://localhost:8210/webSocket?token="+token);
         //打开事件
         websocket.onopen = function () {
             alert("Socket 已打开");
             websocket.send("这是来自客户端的消息:" + location.href + new Date());
         };
         //获得消息事件
         websocket.onmessage = function (msg) {
             alert(msg.data);
         };
         //关闭事件
         websocket.onclose = function () {
             alert("Socket已关闭");
         };
         //发生了错误事件
         websocket.onerror = function () {
             alert("发生了错误");
         }
     });

     //发送消息
     $("#btnSend").click(function () {
         var msg = document.getElementById("inputMsg").value;
         websocket.send("这是来自客户端的消息:" +msg+new Date());
         alert("客户端发送了消息");
     });


     //关闭
     $("#btnClose").click(function () {
         websocket.close();
         alert("客户端关闭了连接");
     });
</script>
</body>

</html>
上一篇 下一篇

猜你喜欢

热点阅读