SpringBoot整合WebSocket实现简易聊天室
创始人
2024-04-24 07:00:30

文章目录

    • 什么是WebSocket ?
    • WebSocket通信模型
    • 为什么需要WebSocket
    • Websocket与http的关系
    • SpringBoot集成WebSocket

什么是WebSocket ?

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

WebSocket通信模型

为什么需要WebSocket

http 通信是单向的,发送请求获取响应,没有请求也就没有响应。

简单理解:

  • HTTP 打电话:客户端问一句服务端答一句

  • WebSocket 打电话:双向对话

Websocket与http的关系

相同点:

  • 都是基于tcp的,都是可靠性传输协议

  • 都是应用层协议

不同点:

  • WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息

  • HTTP是单向的

  • WebSocket是需要浏览器和服务器握手进行建立连接的而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。

SpringBoot集成WebSocket

maven依赖

		  org.springframework.boot  spring-boot-starter-websocket   

WebSocketConfig

@Configuration  
public class WebSocketConfig {  @Bean  public ServerEndpointExporter serverEndpointExporter() {  return new ServerEndpointExporter();  }  }

WebSocketService

@Slf4j
@Service
@ServerEndpoint(value = "/myService/{userId}")
public class WebSocketService {/*** 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/private static AtomicInteger onlineCount = new AtomicInteger(0);;/*** concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();/*** concurrent包的线程安全Set,用来存放每个客户端对应的session对象。*/private static ConcurrentHashMap sessionMap = new ConcurrentHashMap<>();/*** 与某个客户端的连接会话,需要通过它来给客户端发送数据*/private Session session;private String userId = "";/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session,@PathParam("userId") String userId) {this.session = session;this.userId = userId;if(webSocketMap.containsKey(userId) && sessionMap.containsKey(userId)){webSocketMap.remove(userId);sessionMap.remove(userId);sessionMap.put(userId,session);webSocketMap.put(userId,this);}else{webSocketMap.put(userId,this);sessionMap.put(userId,session);addOnlineCount();}log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());}/*** 连接关闭调用的方法*/@OnClosepublic void onClose() {if(webSocketMap.containsKey(userId)){webSocketMap.remove(userId);subOnlineCount();}log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());}/*** 收到客户端消息后调用的方法*/@OnMessagepublic void onMessage(String message, Session session) {this.session = session;log.info("收到客户端消息 -> {}",message);//服务端收到客户端的消息并推送给客户端sendMessage(message);}/*** 发生错误时调用*/@OnErrorpublic void onError(Session session, Throwable error) {log.error(error.getMessage());}/*** 实现服务器主动推送   可以通过controller调用此方法实现主动推送*/public void sendMessage(String message){try {Set> entries = sessionMap.entrySet();for (Map.Entry next : entries) {Session session = next.getValue();session.getBasicRemote().sendText(this.userId + "说" + message);}} catch (IOException e) {log.error(e.getMessage());}}public static synchronized int getOnlineCount() {return onlineCount.get();}public static synchronized void addOnlineCount() {WebSocketService.onlineCount.getAndIncrement();}public static synchronized void subOnlineCount() {WebSocketService.onlineCount.getAndDecrement();}
}

WebSocket.html



websocket通讯

userId:

msg:

操作:

操作:

测试
在这里插入图片描述

相关内容

热门资讯

demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...