webSocket

package com.websocket.socket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Slf4j
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Autowired
    private MyHandshake handshake;

    @Autowired
    private MyHandler handler;

    /*
    配置websocket入口,允许访问的域,注册handler,sockJs支持和拦截器
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        //注册和路由的功能,当客户端发起websocket链接,把/path交给对应的handler解决,而不实现具体的业务逻辑,是一个收集和任务分发的中心
        //setAllowedOrigins(String[] doamins),允许指定的域名或IP建立长连接,如果不限使用,用*表示,如果给定域名,必须以http或者https开头
        //addInterceptors,这个就是为handler添加拦截器,可以在调用handler前后加入自己的逻辑代码
        webSocketHandlerRegistry.addHandler(handler, "/echo").addInterceptors(handshake).setAllowedOrigins("*");
        
        webSocketHandlerRegistry.addHandler(handler, "/sockjs/echo").addInterceptors(handshake).setAllowedOrigins("*").withSockJS();
    }
}

1.@Configuration注解标记在项目启动时加载以下配置,一个就是请求进来的拦截器hanshake,一个是请求进来后的处理类handler

 $(function () {
        var websocket;
        if ('WebSocket' in window) {
            console.log("WebSocket");
            websocket = new WebSocket("ws://localhost:8080/echo");
        } else if ('MozWebSocket' in window) {
            console.log("MozWebSocket");
            websocket = new MozWebSocket("ws://echo");
        } else {
            console.log("SockJS");
            websocket = new SockJS("http://127.0.0.1:8080/sockjs/echo");
        }
        websocket.onopen = function (evnt) {
            console.log("链接服务器成功!", evnt.data);
        };
        websocket.onmessage = function (evnt) {
            console.log('收到消息:', evnt.data);
            var json = JSON.parse(evnt.data);
            if (json.hasOwnProperty('users')) {
                var users = json.users;
                for (var i = 0; i < users.length; i++) {
                    $("#inputGroupSelect01").append('<option value="' + users[i] + '">' + users[i] + '</option>');
                }
            } else {
                //打印消息
                toast(json.msg, 'info')
            }
        };

2:new WebSocket建立websocket的通道,执行时请求会被handshake拦截,

beforeHandshake这个方法中有个map的参数,这个东西其实就是WebSocketSession,我实在没看懂。。。看了源码也没懂为什么这个东西是
WebSocketSession
package com.websocket.socket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

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

/**
 *beforeHandshake 握手之前
 * afterHandshake 握手之后
 */
@Slf4j
@Service
public class MyHandshake  implements HandshakeInterceptor {


    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
        if (serverHttpRequest instanceof ServletServerHttpRequest) {
            HttpServletRequest servletRequest = ((ServletServerHttpRequest) serverHttpRequest).getServletRequest();
            // 从session中获取到当前登录的用户信息. 作为socket的账号信息. session的的WEBSOCKET_USERNAME信息,在用户打开页面的时候设置.
            String userName = (String) servletRequest.getSession().getAttribute("WEBSOCKET_USERNAME");
            map.put("WEBSOCKET_USERNAME", userName);
        }
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {

    }
}

 

3:执行完handshake后执行这个hander处理,

String userName = (String) webSocketSession.getAttributes().get("WEBSOCKET_USERNAME");这个东西能get到你在handshake中在map中put的东西。。。因为那个map塞值全塞到
webSocketSession里面了。。。
public class MyHandler implements WebSocketHandler {

    /**
     * 为了保存在线用户信息,在方法中新建一个list存储一下【实际项目依据复杂度,可以存储到数据库或者缓存】
     */
    private final static List<WebSocketSession> SESSIONS = Collections.synchronizedList(new ArrayList<>());

    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        System.out.println("链接成功......");
        SESSIONS.add(webSocketSession);
        String userName = (String) webSocketSession.getAttributes().get("WEBSOCKET_USERNAME");
        if (userName != null) {
            JSONObject obj = new JSONObject();
            // 统计一下当前登录系统的用户有多少个
            obj.put("count", SESSIONS.size());
            users(obj);
            webSocketSession.sendMessage(new TextMessage(obj.toJSONString()));
        }
    }

这个代码,引用https://www.cnblogs.com/nosqlcoco/p/5860730.html

转载于:https://www.cnblogs.com/zitongcc/p/11097659.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值