大家好,我是小悟。
一、WebSocket是啥?🤔
想象一下这个场景:你(客户端)和服务器是一对异地恋情侣📞
传统HTTP通信(像发短信):
- 你:"在干嘛?"(发送请求)
- 等待...(服务器处理)
- 服务器:"在吃饭"(返回响应)
- 聊天结束,连接断开
- 10秒后你又问:"吃完没?"(重新建立连接)
- 重复以上步骤...累不累?流量费不要钱啊!
WebSocket通信(像打电话):
- 你:"喂,能听到吗?"(握手)
- 服务器:"听到啦,随时聊!"(握手成功)
- 然后你们可以:
- 你:"今天天气不错"
- 服务器:"是啊,适合出去玩"
- 服务器:"对了,你快递到了"
- 你:"太好了!"
- 想聊多久聊多久,不用挂断!💑
简单说,WebSocket就是那个不用反复拨号、永远在线的爱情热线!而且它是双向的------服务器可以主动撩你,不用你总是先开口。
二、详细步骤:手把手教你"煲电话粥"📱
第1步:加依赖(准备电话机)
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
第2步:配置WebSocket(安装电话总机)
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myHandler(), "/chat")
.setAllowedOrigins("*"); // 允许所有异地恋(生产环境别这么干!)
}
@Bean
public WebSocketHandler myHandler() {
return new MyWebSocketHandler();
}
}
第3步:实现处理器(训练话务员)
@Component
public class MyWebSocketHandler extends TextWebSocketHandler {
// 用户列表(记住谁在打电话)
private static final Map<String, WebSocketSession> users = new ConcurrentHashMap<>();
/**
* 接通电话后的第一句
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) {
String userId = getUserId(session);
users.put(userId, session);
System.out.println("👋 用户 " + userId + " 上线了!");
sendMessage(session, "系统:欢迎来到聊天室!输入 'bye' 可以挂断哦~");
// 广播有人上线
broadcast("系统:用户 " + userId + " 悄悄潜入聊天室...");
}
/**
* 处理对方说的话
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String userId = getUserId(session);
String payload = message.getPayload();
System.out.println("📩 收到来自 " + userId + " 的消息: " + payload);
if ("bye".equalsIgnoreCase(payload)) {
// 说再见就挂电话
session.close();
return;
}
// 广播消息(让所有人都听到)
String formattedMsg = userId + " 说: " + payload;
broadcast(formattedMsg);
}
/**
* 电话出问题了(信号不好)
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
System.out.println("❌ 信号不好,用户 " + getUserId(session) + " 掉线了");
users.remove(getUserId(session));
}
/**
* 电话挂了(正常挂断)
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
String userId = getUserId(session);
users.remove(userId);
System.out.println("👋 用户 " + userId + " 下线了");
broadcast("系统:用户 " + userId + " 挥一挥衣袖,带走了所有云彩~");
}
/**
* 群发消息(广播)
*/
private void broadcast(String message) {
users.forEach((id, session) -> {
if (session.isOpen()) {
sendMessage(session, message);
}
});
}
/**
* 发送消息(确保安全)
*/
private void sendMessage(WebSocketSession session, String message) {
try {
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
System.out.println("💥 发送消息失败: " + e.getMessage());
}
}
/**
* 从session里提取用户ID(实际项目从token取)
*/
private String getUserId(WebSocketSession session) {
// 这里简化处理,实际应该从认证信息获取
return session.getId().substring(0, 8);
}
}
第4步:前端客户端(你的手机)
<!DOCTYPE html>
<html>
<head>
<title>WebSocket聊天室</title>
<style>
body { font-family: Arial; max-width: 600px; margin: 0 auto; padding: 20px; }
#messages { border: 1px solid #ccc; height: 300px; overflow-y: auto; padding: 10px; margin-bottom: 10px; }
.message { margin: 5px 0; padding: 8px; border-radius: 5px; }
.system { background-color: #f0f0f0; color: #666; }
.user { background-color: #e3f2fd; }
</style>
</head>
<body>
<h2>📱 WebSocket聊天室</h2>
<div id="messages"></div>
<input type="text" id="messageInput" placeholder="输入消息...">
<button onclick="sendMessage()">发送</button>
<button onclick="disconnect()" style="color: red;">挂断电话</button>
<script>
let socket = null;
// 自动连接
window.onload = function() {
connect();
};
function connect() {
// 换成你的服务器地址
socket = new WebSocket('ws://localhost:8080/chat');
socket.onopen = function() {
addMessage('系统', '电话接通啦!开始聊天吧~', 'system');
};
socket.onmessage = function(event) {
const msg = event.data;
if (msg.startsWith('系统:')) {
addMessage('系统', msg.substring(3), 'system');
} else if (msg.includes('说:')) {
const parts = msg.split('说:');
addMessage(parts[0], parts[1], 'user');
}
};
socket.onclose = function() {
addMessage('系统', '电话已挂断,点击发送可重连', 'system');
};
socket.onerror = function() {
addMessage('系统', '信号不好,请检查网络', 'system');
};
}
function sendMessage() {
const input = document.getElementById('messageInput');
const message = input.value.trim();
if (!socket || socket.readyState !== WebSocket.OPEN) {
connect();
setTimeout(() => sendMessage(), 500);
return;
}
if (message) {
socket.send(message);
input.value = '';
}
}
function disconnect() {
if (socket) {
socket.send('bye');
socket.close();
}
}
function addMessage(sender, content, type) {
const messagesDiv = document.getElementById('messages');
const msgDiv = document.createElement('div');
msgDiv.className = `message ${type}`;
msgDiv.innerHTML = `<strong>${sender}:</strong> ${content}`;
messagesDiv.appendChild(msgDiv);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
// 回车发送
document.getElementById('messageInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') sendMessage();
});
</script>
</body>
</html>
第5步:进阶功能(VIP服务)
// 1. 心跳检测(防止假死)
@Component
public class HeartbeatScheduler {
@Scheduled(fixedRate = 30000) // 每30秒
public void checkAlive() {
MyWebSocketHandler.getUsers().forEach((id, session) -> {
try {
session.sendMessage(new TextMessage("ping"));
} catch (IOException e) {
// 用户可能已经溜了
}
});
}
}
// 2. 私聊功能(悄悄话)
public void sendPrivateMessage(String fromUserId, String toUserId, String message) {
WebSocketSession targetSession = users.get(toUserId);
if (targetSession != null && targetSession.isOpen()) {
sendMessage(targetSession, "【私聊】" + fromUserId + " 对你说: " + message);
}
}
// 3. 在线用户列表
public List<String> getOnlineUsers() {
return new ArrayList<>(users.keySet());
}
三、总结:WebSocket的"爱情哲学"💕
WebSocket的优势:
- 省流量:一次握手,长久通话(HTTP每次都要说"喂,能听到吗?")
- 实时性:服务器可以主动"撩"客户端(推送消息)
- 低延迟:不用反复建立连接(像永远不挂的电话)
适用场景:
- ✅ 聊天应用(微信、钉钉)
- ✅ 实时游戏(王者荣耀的队友位置)
- ✅ 股票行情(股价跳动)
- ✅ 协同编辑(腾讯文档)
- ✅ 物联网监控(设备状态实时更新)
注意事项:
- 连接管理:用户多了要小心,别把服务器压垮
- 心跳机制:定期说句话,确认对方还在线
- 重连策略:网络断了要自动重拨
- 安全性:别让陌生人随便"打电话"进来
- 协议兼容:有些老浏览器不支持WebSocket
最后:
为什么WebSocket比HTTP更适合聊天?
因为HTTP每次聊天前都要问:"在吗?"
等收到"在"的时候,你已经不想聊了...😂
WebSocket就像一段好的感情------不需要反复确认,始终彼此连接,随时可以说话。用它来构建实时应用,让数据像对话一样自然流动吧!
实战建议:从小聊天室开始,慢慢添加房间管理、消息历史、文件传输等功能。记住,能力越大,责任越大------实时应用很酷,但也需要考虑性能、扩展性和安全性哦!

谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。
您的一键三连,是我更新的最大动力,谢谢
山水有相逢,来日皆可期,谢谢阅读,我们再会
我手中的金箍棒,上能通天,下能探海