引入依赖
<!--springboot依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.13</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!--springboot websocket依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author jihongda
* @date 2022/5/9 17:14
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
连接服务类
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author jihongda
* @date 2022/5/9 15:50
*/
@Slf4j
@Component
@ServerEndpoint("/chat/{userId}")
public class WebSocketEndPoint {
//每次来一个连接会生成一个本类实例,保存在此,key为userId
private static final Map<String, WebSocketEndPoint> INSTANCE_MAP = new ConcurrentHashMap<>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/**
* 根据userId获取连接所在的实例.
* @param userId userId
* @return 实例
*/
public static WebSocketEndPoint getInstanceByUserId(String userId) {
return INSTANCE_MAP.get(userId);
}
/**
* 发送消息给指定客户端.
* @param userId 客户端userId
* @param message 消息.
*/
public static void sendMessageToClient(String userId, String message) {
WebSocketEndPoint instance = getInstanceByUserId(userId);
if (instance == null) {
log.info("用户:{} 的会话不存在!", userId);
return;
}
instance.session.getAsyncRemote().sendText(message);
}
/**
* 连接建立成功调用的方法.
* @param session Session
* @param userId 前端生成唯一id
*/
@OnOpen
public void onOpen(final Session session, @PathParam("userId") final String userId) {
INSTANCE_MAP.put(userId, this);
this.session = session;
log.info("web连接成功 userId:{}", userId);
}
/**
* 连接关闭调用的方法.
*/
@OnClose
public void onClose() {
for (Map.Entry<String, WebSocketEndPoint> entry : INSTANCE_MAP.entrySet()) {
if (Objects.equals(entry.getValue(), this)) {
log.info("web连接关闭, userId:{}", entry.getKey());
INSTANCE_MAP.remove(entry.getKey());
}
}
}
/**
* 收到客户端消息后调用的方法.
* @param session Session
* @param message 客户端发送过来的消息
* @param userId 用户唯一id
*/
@OnMessage
public void onMessage(final Session session, final String message, final @PathParam("userId") String userId) {
log.info("接收客户端消息message:{}, userId:{}", message, userId);
}
/**
* 发生错误时调用.
* @param session Session
* @param error Throwable
*/
@OnError
public void onError(final Session session, final Throwable error) {
log.info("连接发生错误:{}", error.getMessage());
error.printStackTrace();
}
}
测试
启动项目
百度“websocket在线测试”,然后随便找一个进去
输入连接地址:ws://127.0.0.1:5113/chat/abcde
控制台输出