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