在项目中使用WebSocket实现实时通信
WebSocket提供了一种在客户端和服务器之间建立持久连接的方式,可以实现实时数据交换。下面我将展示如何在前端项目中集成WebSocket功能。
设计思路
我将创建一个简单的聊天室界面来演示WebSocket的使用,包含以下功能:
- 建立WebSocket连接
- 发送和接收消息
- 显示连接状态
- 错误处理和重连机制
实现代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket 聊天室</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f5f7fa;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
header {
background: #4a6ee0;
color: white;
padding: 20px;
text-align: center;
}
.status-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background: #f0f4ff;
border-bottom: 1px solid #e0e6ff;
}
.status {
display: flex;
align-items: center;
}
.status-indicator {
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 8px;
}
.connected {
background: #4caf50;
}
.disconnected {
background: #f44336;
}
.chat-container {
padding: 20px;
height: 400px;
overflow-y: auto;
background: #fafbff;
}
.message {
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 18px;
max-width: 80%;
word-break: break-word;
}
.received {
background: #e6eeff;
border-top-left-radius: 4px;
align-self: flex-start;
}
.sent {
background: #4a6ee0;
color: white;
border-top-right-radius: 4px;
margin-left: auto;
}
.message-input {
display: flex;
padding: 15px;
border-top: 1px solid #e0e6ff;
background: #fafbff;
}
input {
flex: 1;
padding: 12px 15px;
border: 1px solid #d0d9ff;
border-radius: 20px;
outline: none;
font-size: 16px;
}
button {
background: #4a6ee0;
color: white;
border: none;
border-radius: 20px;
padding: 12px 20px;
margin-left: 10px;
cursor: pointer;
font-weight: bold;
transition: background 0.3s;
}
button:hover {
background: #3a5ec0;
}
button:disabled {
background: #cccccc;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>WebSocket 聊天室</h1>
</header>
<div class="status-bar">
<div class="status">
<div class="status-indicator disconnected" id="statusIndicator"></div>
<span id="statusText">未连接</span>
</div>
<button id="connectButton">连接</button>
</div>
<div class="chat-container" id="chatContainer">
<div class="message received">
欢迎使用聊天室!请点击"连接"按钮开始。
</div>
</div>
<div class="message-input">
<input type="text" id="messageInput" placeholder="输入消息..." disabled>
<button id="sendButton" disabled>发送</button>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const statusIndicator = document.getElementById('statusIndicator');
const statusText = document.getElementById('statusText');
const connectButton = document.getElementById('connectButton');
const chatContainer = document.getElementById('chatContainer');
const messageInput = document.getElementById('messageInput');
const sendButton = document.getElementById('sendButton');
let websocket = null;
const serverUrl = 'wss://echo.websocket.org'; // 这是一个公共的WebSocket测试服务器
// 更新连接状态UI
function updateConnectionStatus(connected) {
if (connected) {
statusIndicator.className = 'status-indicator connected';
statusText.textContent = '已连接';
connectButton.textContent = '断开';
messageInput.disabled = false;
sendButton.disabled = false;
} else {
statusIndicator.className = 'status-indicator disconnected';
statusText.textContent = '未连接';
connectButton.textContent = '连接';
messageInput.disabled = true;
sendButton.disabled = true;
}
}
// 添加消息到聊天窗口
function addMessage(content, isSent = false) {
const messageElement = document.createElement('div');
messageElement.className = `message ${isSent ? 'sent' : 'received'}`;
messageElement.textContent = content;
chatContainer.appendChild(messageElement);
// 滚动到底部
chatContainer.scrollTop = chatContainer.scrollHeight;
}
// 建立WebSocket连接
function connect() {
try {
websocket = new WebSocket(serverUrl);
websocket.onopen = function(event) {
updateConnectionStatus(true);
addMessage('已连接到服务器');
};
websocket.onmessage = function(event) {
addMessage(event.data);
};
websocket.onclose = function(event) {
updateConnectionStatus(false);
addMessage('连接已关闭');
websocket = null;
};
websocket.onerror = function(error) {
console.error('WebSocket错误:', error);
addMessage('发生错误,连接已断开');
updateConnectionStatus(false);
};
} catch (error) {
console.error('无法建立连接:', error);
addMessage('无法连接到服务器: ' + error.message);
updateConnectionStatus(false);
}
}
// 关闭WebSocket连接
function disconnect() {
if (websocket) {
websocket.close();
}
}
// 发送消息
function sendMessage() {
const message = messageInput.value.trim();
if (message && websocket && websocket.readyState === WebSocket.OPEN) {
websocket.send(message);
addMessage(message, true);
messageInput.value = '';
}
}
// 连接/断开按钮点击事件
connectButton.addEventListener('click', function() {
if (websocket && websocket.readyState === WebSocket.OPEN) {
disconnect();
} else {
connect();
}
});
// 发送按钮点击事件
sendButton.addEventListener('click', sendMessage);
// 按Enter键发送消息
messageInput.addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
sendMessage();
}
});
});
</script>
</body>
</html>
使用说明
- 页面加载后,点击"连接"按钮建立WebSocket连接
- 连接成功后,可以在输入框中输入消息并点击"发送"或按Enter键
- 发送的消息会显示在右侧(蓝色),接收的消息显示在左侧(浅蓝色)
- 可以随时点击"断开"按钮结束连接
实际项目中的注意事项
- 生产环境URL:示例中使用的是测试服务器,实际项目中应替换为您的WebSocket服务器地址
- 安全连接:生产环境应使用
wss://
(WebSocket Secure)而不是ws://
- 错误处理:需要根据实际需求完善错误处理和重连机制
- 身份验证:实际应用中通常需要在建立连接时进行身份验证
- 数据格式:通常使用JSON格式进行复杂数据交换
扩展功能
在实际项目中,您可能需要添加:
- 心跳机制保持连接活跃
- 消息重发机制确保消息送达
- 连接状态监控和自动重连
- 支持不同的消息类型(文本、图片、文件等)
- 用户身份标识和会话管理