SpringBoot整合WebSocket遇到的坑

websocket failed: Error during WebSocket handshake: Unexpected response

1、pom.xml 中引入 spring-boot-starter-websocket

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

2、注入 ServerEndpointExporter

@Configuration
public class WebSocketConfig {
    /**
     * 服务器节点
     *
     * 如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

3、websocket接收类

/**
 * ServerEndpoint
 * <p>
 * 使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。
 * <p>
 * 虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
 *
 * @author han
 * @since 2020/3/17
 */
@ServerEndpoint("/chat/{uid}") //客户端建立连接的地址
@Component
public class ChatServer {
    /**
     * 用户业务对象 这里要注意service的注入方式
     */
    private UserService userService = SpringContextUtil.getBean(UserService.class);

    /**
     * session集合
     */
    private static Map<String, Session> sessions = new ConcurrentHashMap<>();

    /**
     * 连接回调方法
     *
     * @param session  与客户端的WebSocket连接会话
     * @param uid 用户id,WebSocket支持路径参数
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("uid") String uid) {
        livingSessions.put(session.getId(), session);
        sendMessageToAll(uid + "来了");
    }

    /**
     * 收到客户端消息的回调方法
     *
     * @param message 客户端传过来的消息
     * @param session 对应的session
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("uid") String uid) {
        sendMessageToAll(uid + " : " + message);
    }


    /**
     * 发生错误的回调方法
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    /**
     * 关闭连接的回调方法
     */
    @OnClose
    public void onClose(Session session, @PathParam("uid") String uid) {
        livingSessions.remove(session.getId());
        sendMessageToAll(uid + " 关闭连接");
    }


    /**
     * 单独发送消息
     *
     * @param session
     * @param message
     */
    public void sendMessage(Session session, String message) {
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 群发消息
     *
     * @param message
     */
    public void sendMessageGroup(String message) {
        livingSessions.forEach((sessionId, session) -> {
            sendMessage(session, message);
        });
    }

}

4、如何使用外部tomcat容器启动websocket

1. 删除ServerEndpointExporter注入bean
2. websocket接收类删除@Component
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容