/**
 * 握手拦截器
 */
@Component
@Slf4j
public class WsInterceptor extends HttpSessionHandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        log.info("{}开始握手...", request.getRemoteAddress());
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
        log.info("{}握手结束...", request.getRemoteAddress());
        super.afterHandshake(request, response, wsHandler, ex);
    }
}

可以定义一个自己的拦截器,只要去继承父类重写里面的方法即可实现自定义在期间的操作

同时可以去继承他的主处理程序,这样可以对连接建立前后做相应的操作

/**
 * web socket 主处理程序
 */
@Slf4j
@Component
public class WsHandler extends AbstractWebSocketHandler {

    private static final Map<String, SessionBean> sessionBeanMap;
    private static final AtomicInteger clientIdMaker;//考虑线程安全
    private static final StringBuffer stringBuffer;//存储信息

    //初始化
    static {
        sessionBeanMap = new ConcurrentHashMap<>();
        clientIdMaker = new AtomicInteger(0);
        stringBuffer = new StringBuffer();
    }

这里因为每一条连接建立后(session)都是一条单独的线程,我们需要使用线程安全的Map类型和Integer类型,这里可变字符串StringBuffer只是用来临时存储消息。这里就举一个简单的例子,说明建立连接后的操作

     /**
     * 连接建立成功后
     *
     * @param session
     * @throws Exception
     */

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());//返回当前的值并且自增
        sessionBeanMap.put(session.getId(), sessionBean);
        log.info("{}连接成功...", sessionBean.getClientId());
        super.afterConnectionEstablished(session);
        stringBuffer.append(sessionBean.getClientId() + ":" + "连接成功" + "\n");
        //进行群发
        sendAll(sessionBeanMap);
    }

我们可以从每一条session里面取出对应的id存储到我们自定义的bean中,方便区分每一个用户的连接

重要的部分来了

@Configuration
@EnableWebSocket
public class WsConfig implements WebSocketConfigurer {
    @Resource
    private WsHandler wsHandler;
    @Resource
    private WsInterceptor wsInterceptor;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //注册主要处理器
        registry.addHandler(wsHandler, "/ws").addInterceptors(wsInterceptor).setAllowedOrigins("*");
    }
}

我们创建一个配置类将我们自己定义的拦截器主处理器等注册进入我们实现的注册器中,@Resource注解将我们自定义的bean注入进来同时使用@EnableWebSocket注解被其识别

引文使用的springboot建立的工程 我们直接引入官方已经绑定好的maven依赖即可

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
 </dependency>

文章作者: Administrator
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 叶秋の小窝
Code java
喜欢就支持一下吧