WebSocket 从入门到进阶实战

好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受.

聊天系统是WebSocket的最佳实践,以下是使用WebSocket技术实现的一个聊天系统的关键代码,可以通过这些关键代码,更加清晰的了解 WebSocket 在项目中的使用情况(本实战将以springboot框架进行展开)。

目录

[一、前端代码(HTML + JavaScript)](#一、前端代码(HTML + JavaScript))

前端页面:chat.html

[二、Java 后端代码(Spring Boot)](#二、Java 后端代码(Spring Boot))

[1. 添加依赖](#1. 添加依赖)

[2. 配置 WebSocket](#2. 配置 WebSocket)

[3. 创建 WebSocket 服务端类](#3. 创建 WebSocket 服务端类)

[4. 创建 Spring Boot 应用主类](#4. 创建 Spring Boot 应用主类)

三、异常处理和性能优化

[1. 异常处理](#1. 异常处理)

[2. 性能优化](#2. 性能优化)

四、运行和测试

五、总结


一、前端代码(HTML + JavaScript)

前端页面:chat.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实时聊天室</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            background-color: #f4f4f4;
        }
        #chat-container {
            width: 80%;
            max-width: 600px;
            background: white;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }
        #chat-header {
            background: #007bff;
            color: white;
            padding: 10px;
            text-align: center;
            font-size: 1.5em;
        }
        #chat-body {
            height: 300px;
            overflow-y: auto;
            padding: 10px;
            border-bottom: 1px solid #ddd;
        }
        #chat-footer {
            display: flex;
            padding: 10px;
        }
        #chat-footer input {
            flex: 1;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-right: 10px;
        }
        #chat-footer button {
            padding: 8px 16px;
            border: none;
            background: #007bff;
            color: white;
            border-radius: 4px;
            cursor: pointer;
        }
        #chat-footer button:hover {
            background: #0056b3;
        }
        .message {
            margin-bottom: 10px;
        }
        .message .username {
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div id="chat-container">
        <div id="chat-header">实时聊天室</div>
        <div id="chat-body"></div>
        <div id="chat-footer">
            <input type="text" id="message-input" placeholder="输入消息...">
            <button onclick="sendMessage()">发送</button>
        </div>
    </div>

    <script>
        const chatBody = document.getElementById('chat-body');
        const messageInput = document.getElementById('message-input');
        let webSocket = null;

        // 连接 WebSocket 服务器
        function connect() {
            if ('WebSocket' in window) {
                webSocket = new WebSocket("ws://localhost:8080/chat");
                webSocket.onopen = function() {
                    console.log("已连接到服务器");
                };
                webSocket.onmessage = function(event) {
                    const message = JSON.parse(event.data);
                    displayMessage(message);
                };
                webSocket.onclose = function() {
                    console.log("连接已关闭");
                };
                webSocket.onerror = function(error) {
                    console.error("WebSocket 发生错误:", error);
                };
            } else {
                alert("您的浏览器不支持 WebSocket!");
            }
        }

        // 发送消息
        function sendMessage() {
            const messageText = messageInput.value.trim();
            if (messageText) {
                const message = {
                    username: "用户" + Math.floor(Math.random() * 100), // 模拟用户名
                    text: messageText
                };
                webSocket.send(JSON.stringify(message));
                messageInput.value = '';
            }
        }

        // 显示消息
        function displayMessage(message) {
            const messageElement = document.createElement('div');
            messageElement.classList.add('message');
            messageElement.innerHTML = `<span class="username">${message.username}:</span> ${message.text}`;
            chatBody.appendChild(messageElement);
            chatBody.scrollTop = chatBody.scrollHeight; // 滚动到底部
        }

        // 页面加载时连接 WebSocket
        window.onload = connect;
    </script>
</body>
</html>

二、Java 后端代码(Spring Boot)

1. 添加依赖

pom.xml 文件中添加 WebSocket 依赖:

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2. 配置 WebSocket

创建一个配置类 WebSocketConfig

java 复制代码
package com.example.websocket.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
3. 创建 WebSocket 服务端类

创建一个 WebSocket 服务端类 ChatServer

java 复制代码
package com.example.websocket.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@ServerEndpoint("/chat")
@Component
public class ChatServer {
    private static final Logger log = LoggerFactory.getLogger(ChatServer.class);
    private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());

    @OnOpen
    public void onOpen(Session session) {
        sessions.add(session);
        log.info("新用户连接: " + session.getId());
        sendMessageToAll("系统通知: 有新用户加入了聊天室!");
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到来自用户的消息: " + message);
        sendMessageToAll(message);
    }

    @OnClose
    public void onClose(Session session) {
        sessions.remove(session);
        log.info("用户断开连接: " + session.getId());
        sendMessageToAll("系统通知: 有用户离开了聊天室!");
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        log.error("WebSocket 发生错误: " + throwable.getMessage());
        sessions.remove(session);
    }

    // 向所有用户发送消息
    private void sendMessageToAll(String message) {
        synchronized (sessions) {
            for (Session session : sessions) {
                if (session.isOpen()) {
                    try {
                        session.getBasicRemote().sendText(message);
                    } catch (IOException e) {
                        log.error("发送消息时发生错误: " + e.getMessage());
                    }
                }
            }
        }
    }
}
4. 创建 Spring Boot 应用主类

创建一个主类 ChatApplication

java 复制代码
package com.example.websocket;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ChatApplication {
    public static void main(String[] args) {
        System.out.println("聊天系统正在启动");
        SpringApplication.run(ChatApplication.class, args);
        System.out.println("聊天系统启动完成");
    }
}

三、异常处理和性能优化

1. 异常处理
  • onError 方法中记录错误日志,并从会话集合中移除异常的会话。

  • 在发送消息时捕获 IOException,避免因单个会话异常导致整个应用崩溃。

2. 性能优化
  • 使用 CopyOnWriteArraySet 存储会话集合,确保线程安全。

  • 在发送消息时,通过同步块确保线程安全,避免并发问题。

四、运行和测试

  1. 启动后端服务 :运行 ChatApplication 类启动 Spring Boot 应用。

  2. 打开前端页面 :在浏览器中打开 chat.html 文件。

  3. 测试聊天功能 :在多个浏览器窗口中打开 chat.html,输入消息并发送,观察消息是否实时同步到其他窗口。

五、总结

以上代码实现了一个简单的实时聊天系统,前端使用 HTML 和 JavaScript,后端使用 Spring Boot 和 WebSocket。代码中包含了异常处理和性能优化的措施,确保系统的稳定性和高效性。通过 WebSocket 的实时通信能力,用户可以即时发送和接收消息,提升用户体验。

关注我,带你了解更多IT知识

搜索codingba 或 "码出精彩" ,和我一起探讨软件研发的那些事。

相关推荐
斯普信专业组2 小时前
IP隧道技术中数据包头部的变化分析:必然增加的封装机制
网络·tcp/ip·php
Ro小陌2 小时前
C# TCP协议全面指南:从可靠传输到企业级高并发的深度实践
网络·tcp/ip·c#
北极光SD-WAN组网4 小时前
SD-WAN技术在远程光伏电站接入场景中的应用实践与深度解析
服务器·网络·数据库
走过冬季5 小时前
TCP与UDP区别及应用场景详解
网络协议·tcp/ip·udp
互联网搬砖老肖6 小时前
运维打铁:生产服务器用户权限管理方案全解析
运维·服务器·网络
上海云盾商务经理杨杨6 小时前
2025年高防IP与游戏盾深度对比:如何选择最佳防护方案?
网络协议·tcp/ip·安全·web安全·游戏
不愧是你呀7 小时前
深度剖析并发I/O模型select、poll、epoll与IOCP核心机制
linux·服务器·网络·windows
Think Spatial 空间思维7 小时前
【安全攻防与漏洞】HTTPS中的常见攻击与防御
网络协议·安全·https·漏洞·攻防·防御
UrSpecial7 小时前
HTTPS核心机制拆解
网络协议·http·https