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

http 通信是单向的,发送请求获取响应,没有请求也就没有响应。
简单理解:
HTTP 打电话:客户端问一句服务端答一句
WebSocket 打电话:双向对话


相同点:
都是基于tcp的,都是可靠性传输协议
都是应用层协议
不同点:
WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息
HTTP是单向的
WebSocket是需要浏览器和服务器握手进行建立连接的而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。
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:
操作:
操作:
测试
