java WebSocket 使用

1、创建WebSocket配置类

java 复制代码
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(chatWebSocketHandler(), "/chat/ws")
                .setAllowedOrigins("https://yourdomain.com")  // 生产环境配置具体域名
                .withSockJS(); // 兼容不支持 WebSocket 的浏览器
    }

    @Bean
    public WebSocketHandler chatWebSocketHandler() {
        return new ChatWebSocketHandler();
    }
}

2、创建WebSocket和前端的通信类

java 复制代码
/*TextWebSocketHandler‌是 Spring 框架提供的用于处理 WebSocket 文本消息的处理器基类,通过继承该类
*	并重写特定方法,便可以在项目中实现 WebSocket 服务端逻辑。
*	
*	例:1、afterConnectionEstablished:当客户端与服务端成功建立 WebSocket 连接时触发,常用于记录在线用户、初始化会话属性或发送欢迎消息 。
*   2、handleTextMessage:当服务端收到客户端发送的文本消息时触发,是业务逻辑处理的主要入口,可在此解析消息并回复 。
*   3、afterConnectionClosed:当连接正常关闭时触发,用于清理资源、移除离线用户会话或记录日志 。
*   4、handleTransportError:当通信过程中出现异常(如网络中断)时触发,用于错误处理和告警 。
*/
public class ChatWebSocketHandler extends TextWebSocketHandler {
    // 存储所有在线客户端连接
    private final Set<WebSocketSession> sessions = ConcurrentHashMap.newKeySet();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        // 新客户端连接处理
        sessions.add(session);
        System.out.println("新客户端连接: " + session.getId());
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 接收客户端消息并广播给所有在线用户
        String payload = message.getPayload();
        System.out.println("收到消息: " + payload);
        
        // 消息广播
        for (WebSocketSession webSocketSession : sessions) {
            if (webSocketSession.isOpen()) {
                webSocketSession.sendMessage(new TextMessage("广播消息: " + payload));
            }
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        // 客户端连接关闭处理
        sessions.remove(session);
        System.out.println("客户端断开连接: " + session.getId());
    }
    
    @Override
    protected void handleTransportError(WebSocketSession session, TextMessage message) throws Exception {
        String userId = getUserIdFromSession(session);
        
        // 1. 记录详细错误日志
        log.error("WebSocket传输错误,用户ID:{},会话ID:{},错误信息:{}", 
                  userId, session.getId(), exception.getMessage(), exception);
    }
}

3、前端简单实现

javascript 复制代码
// 创建 WebSocket 连接
const socket = new WebSocket('wss://yourdomain.com/chat/ws');

// 连接成功回调
socket.onopen = function(event) {
    console.log('WebSocket 连接已建立');
    socket.send('Hello, Server!');
};

// 接收消息回调
socket.onmessage = function(event) {
    const message = event.data;
    console.log('收到服务器消息:', message);
    // 更新UI展示消息
};

// 连接关闭回调
socket.onclose = function(event) {
    console.log('WebSocket 连接已关闭');
    // 实现自动重连逻辑
    setTimeout(() => initWebSocket(), 5000);
};

// 错误处理回调
socket.onerror = function(error) {
    console.error('WebSocket 错误:', error);
};

4、简单使用

java 复制代码
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(photoWebSocketHandler(), "/photo/ws")
                //.setAllowedOrigins("https://localhost:8080")  // 生产环境配置具体域名
                .setAllowedOrigins("*");//也可配置适配所有域名,生产环境不建议
    }

    @Bean
    public WebSocketHandler photoWebSocketHandler() {
        return new PhotoWebSocketHandler();
    }
}

/**
 * 照片推送WebSocket处理器
 */
public class PhotoWebSocketHandler extends TextWebSocketHandler {
    private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        // 每3秒推送一次最新照片
        executor.scheduleAtFixedRate(() -> {
            try {
                // 1. 获取最新照片
                byte[] photoBytes = getLatestPhoto();
                
                // 2. 转换为Base64字符串
                String base64Photo = Base64.getEncoder().encodeToString(photoBytes);
                
                // 3. 推送给前端
                session.sendMessage(new TextMessage(base64Photo));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, 0, 3, TimeUnit.SECONDS);
    }

    /**
     * 获取最新照片(示例方法)
     * @return 照片字节数组
     * @throws IOException IO异常
     */
    private byte[] getLatestPhoto() throws IOException {
        File latestPhoto = new File("photos/latest.jpg");
        return Files.readAllBytes(latestPhoto.toPath());
    }
}
javascript 复制代码
<img id="realTimePhoto" alt="实时照片">
<script>
    const ws = new WebSocket('ws://localhost:8080/photo/ws');
    const imgElement = document.getElementById('realTimePhoto');
    
    ws.onmessage = function(event) {
        // 接收Base64照片并更新
        imgElement.src = 'data:image/jpeg;base64,' + event.data;
    };
    
    ws.onclose = function() {
        console.log('WebSocket连接已关闭');
    };
</script>
相关推荐
二十雨辰11 分钟前
[学成在线]-01项目背景
java
小小小小钰儿23 分钟前
1.5-Python网络编程
开发语言·网络·python·web安全·计算机·网络安全
hiahiahia12323 分钟前
实现完整 Tool Dispatcher
开发语言·前端
AC赳赳老秦1 小时前
公开音频转写信息提取:OpenClaw 处理发布会与听证会文本并提取核心决策信息
大数据·开发语言·汇编·数据库·人工智能·deepseek·openclaw
弈栈录1 小时前
Java AI 应用的异步化与高并发设计
java·后端·架构
@yanyu6661 小时前
C编译器安装与第一个C程序
c语言·开发语言
落魄实习生1 小时前
Agent Scope Java 2.x 系列【2】 ReActAgent
java·开发语言
智鸟科技GemeOpen开发者智能设备2 小时前
智能插座二次开发如何接入Home Assistant,从零开始完整工程实现(Python+React)
开发语言·python·物联网·react.js·智能家居
疯狂成瘾者2 小时前
海康 Artemis 接口对接
开发语言·lua