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>
相关推荐
gihigo19981 小时前
FastSLAM2.0(精度优于1.0)MATLAB 实现
开发语言·matlab
Yolo566Q1 小时前
Noah-MP陆面过程模型建模方法与站点、区域模拟实践技术应用
开发语言·python
落叶-IT1 小时前
Java Scanner 类精讲:控制台交互
java·开发语言
chh5632 小时前
C++--string
java·开发语言·网络·c++·学习
Listen·Rain2 小时前
向量化详解
java·人工智能·spring·机器学习·ai
想你依然心痛2 小时前
AUTOSAR Classic Platform架构解析:BSW、RTE与ASW——分层、配置、代码生成
java·架构·实时互动
梦想的旅途22 小时前
企业微信外部群智能自动回复:基于RPA接口的关键词匹配方案
java·开发语言·数据库·机器人·自动化·企业微信
娇气的红酒2 小时前
关于.NET VS JavaEE平台争论的沉思录
java·java-ee·.net
折哥的程序人生 · 物流技术专研2 小时前
第3篇:手写一个饮品制作模板(附代码)
java·设计模式·行为型模式·模版方法模式·钩子方法·代码复用·编程实战