一、添加依赖包
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
二、直接上代码
1、添加配置
/**
* @author fanxf
* @since 2019/11/29 15:40
*/
@Configuration
public class WebSocketConfig {
/**
* socket配置类,往 spring 容器中注入ServerEndpointExporter实例
*
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
2、编写服务类
/**
* @author fanxf
* @since 2019/11/29 15:42
*/
@Slf4j
@Component
@ServerEndpoint("/websocket/{name}")
public class WebSocketServer {
/**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static AtomicInteger online = new AtomicInteger();
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
private static Map<String, Session> sessionPools = new HashMap<>();
/**
* 接收name
*/
private String name = "";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("name") String name) {
sessionPools.put(name, session);
addOnlineCount();
log.info("有新窗口开始监听:" + name + ",当前在线人数为" + online);
try {
sendMessage(session, "success");
} catch (IOException e) {
log.error("websocket IO异常");
e.printStackTrace();
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(@PathParam("name") String name) {
sessionPools.remove(name);
//在线数减1
subOnlineCount();
log.info(name+ "断开webSocket连接!当前在线人数为" + online);
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message) {
//群发消息
for (Session session: sessionPools.values()) {
try {
sendMessage(session, message);
} catch(IOException e){
e.printStackTrace();
continue;
}
}
}
/**
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 实现服务器主动推送
*/
public void sendMessage(Session session, String message) throws IOException{
if(session != null){
session.getBasicRemote().sendText(message);
}
}
/**
* 给指定用户发送消息
* @param name 用户名
* @param message 消息
* @throws IOException
*/
public void sendInfo(String name, String message){
log.info("收到来自窗口" + name + "的信息:" + message);
Session session = sessionPools.get(name);
try {
sendMessage(session, message);
}catch (Exception e){
e.printStackTrace();
}
}
public static void addOnlineCount(){
online.incrementAndGet();
}
public static void subOnlineCount() {
online.decrementAndGet();
}
}
3、测试类
/**
* @author fanxf
* @since 2019/11/29 15:48
*/
@RestController
@RequestMapping("/notify")
public class NotifyController {
@Resource
private WebSocketServer webSocketServer;
/**
* 推送数据接口
*
* @param message
* @return
*/
@RequestMapping("/socket/push")
public BaseResult pushToWeb(String message) {
webSocketServer.onMessage(message);
return BaseResult.newSuccess(message);
}
/**
* 推送给指定用户
*
* @param message
* @return
*/
@RequestMapping("/socket/push/{cid}")
public BaseResult pushToWeb(@PathVariable String cid, String message) {
webSocketServer.sendInfo(cid, message);
return BaseResult.newSuccess(message);
}
}
直接调用onMessage或sendInfo方法进去测试
4、推荐测试工具
地址:在线测试地址
如图:
显示连接已建立,正在等待数据说明连接成功
5、也可调用手写测试类进行模拟测试
到这完成,写的有点马虎,如有不正请指正!