WebSocket的基本使用方法

一. 与HTTP对比

WebSocket 是一种在单个 TCP 连接上实现全双工(双向)通信的网络协议,它解决了传统 HTTP 协议 “请求 - 响应” 模式的局限性,让客户端(如浏览器)和服务器能建立持久连接,实现实时数据交互。

HTTP是短链接且单向通信,只有客户端主动发请求,服务器才能被动响应,无法主动向客户端推数据。WebSocket是长连接且支持双向通信

WebSocket通过一次HTTP握手建立持久TCP连接,之后客户端与服务器可基于该连接全双工、实时双向收发数据,无需反复建立连接。

二. WebSocket的关键特性

  1. 全双工通信:客户端和服务器可同时发送数据,无需等待对方响应。
  2. 持久连接:连接建立后长期保持,除非主动断开(如客户端关闭页面、服务器重启)。
  3. 跨域支持:WebSocket 本身支持跨域(类似 CORS),可通过 Origin 请求头和服务器配置控制跨域权限。
  4. 支持二进制数据:不仅能传文本(如 JSON),还能直接传二进制数据(如图片、音频、视频流),比 HTTP 传输二进制更高效。
  5. 自动重连(需手动实现):原生 WebSocket 不支持自动重连,实际项目中需通过代码逻辑实现(如监听 onclose 事件,延迟后重新发起连接)。

三. WebSocket 的典型应用场景

只要涉及 “实时数据交互” 的场景,WebSocket 都是优选方案:

  • 即时通讯:在线聊天(如微信网页版、企业 IM)、客服对话。
  • 实时通知:订单状态更新(如 “订单已发货”)、消息推送(如点赞提醒)。
  • 实时数据展示:股票 / 数字货币行情、体育赛事比分、监控系统数据(如服务器 CPU 使用率)。
  • 协同工具:多人在线文档编辑(如腾讯文档)、白板协作。
  • 流媒体:低延迟的音视频通话(如 WebRTC 基于 WebSocket 做信令交互)、直播弹幕。

四. 实现步骤

1.前端(浏览器原生API)

浏览器内置WebSocket对象,可直接发送连接和处理数据。

这里以一个简单实现为例

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebSocket Demo</title>
</head>
<body>
    <input id="text" type="text" />
    <button onclick="send()">发送消息</button>
    <button onclick="closeWebSocket()">关闭连接</button>
    <div id="message">
    </div>
</body>
<script type="text/javascript">
    var websocket = null;
    var clientId = Math.random().toString(36).substr(2);

    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        //连接WebSocket节点
        websocket = new WebSocket("ws://localhost:8080/ws/"+clientId);
    }
    else{
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(){
        setMessageInnerHTML("连接成功");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event){
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
	
	//关闭连接
    function closeWebSocket() {
        websocket.close();
    }
</script>
</html>

2. 后端

2.1 导入WebSocket的maven坐标

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2.2 导入WebSocket服务端组件WebSocketServer,用于和客户端通信

/**
 * WebSocket服务
 */
@Component // 交给 Spring 管理
@ServerEndpoint("/ws/{sid}")
//声明这是一个 WebSocket 服务端,路径为 /websocket/{sid}(支持路径参数)
public class WebSocketServer {

    //存放会话对象
    private static Map<String, Session> sessionMap = new HashMap();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        System.out.println("客户端:" + sid + "建立连接");
        sessionMap.put(sid, session);
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        System.out.println("收到来自客户端:" + sid + "的信息:" + message);
    }

    /**
     * 连接关闭调用的方法
     * @param sid
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        System.out.println("连接断开:" + sid);
        sessionMap.remove(sid);
    }

    /**
     * 群发
     * @param message
     */
    public void sendToAllClient(String message) {
        Collection<Session> sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

WebSocketServer的代码格式基本就是这样,可以根据需要自行修改。

2.3 导入配置类WebSocketConfiguration,注册WebSocket的服务端组件

/**
 * WebSocket配置类,用于注册WebSocket的Bean
 */
@Configuration
public class WebSocketConfiguration {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

前端和后端建立 WebSocket 连接的过程可分为 “握手” 和 “连接维持” 两步:

  1. 握手阶段:前端通过 new WebSocket('ws://服务器地址') 发起 HTTP 升级请求,携带 Upgrade: websocket 等头信息;后端验证后返回 101 Switching Protocols 响应,完成协议切换。
  2. 连接维持:握手成功后,TCP 连接保持持久状态,双方通过 WebSocket 帧格式直接双向收发数据,直到某一方主动关闭连接。

核心流程:前端发 HTTP 请求(带升级标识)→ 2. 后端验证并返回 101 响应 → 3. 协议切换为 WebSocket → 4. 基于持久 TCP 连接双向通信。

2.4 导入定时任务类WebSocketTask,定时向客户端推送数据

这相当于一个案例,如何使用WebSocketServer。

@Component
public class WebSocketTask {
    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 通过WebSocket每隔5秒向客户端发送消息
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void sendMessageToClient() {
        webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));
    }
}

当我们想向前端页面推送消息时WebSocketTask的方法sendMessageToClient,如果要传递一个对象,注意将其转换成json格式,例如:

 Map map = new HashMap();
 map.put("type", 2);//1表示来单提醒 2表示客户催单
 map.put("orderId", id);
 map.put("content", "订单号:" + orders.getNumber());

 String json = JSON.toJSONString(map);
 // 通过WebSocket向客户端浏览器推送消息
 webSocketServer.sendToAllClient(json);

### Vue.js 中 WebSocket基本用法 在现代 Web 应用程序中,WebSocket 提供了一种全双工通信信道,在单个 TCP 描述符上操作。这意味着服务器可以主动向客户端推送数据而不需要客户端发起请求。对于实时应用来说非常有用。 #### 创建 WebSocket 实例并连接到服务器 为了在 Vue.js 项目里集成 WebSocket 功能,可以在组件内部创建一个新的 `WebSocket` 对象实例来初始化与服务器之间的连接: ```javascript new Vue({ el: '#app', data() { return { socket: null, messages: [] } }, created() { this.initWebSocket() }, methods: { initWebSocket() { const wsUri = 'ws://yourserveraddress'; // 替换成实际地址 this.socket = new WebSocket(wsUri); this.socket.onopen = function(event) { console.log('Connected to server', event); }; this.socket.onerror = function(errorEvent) { console.error('Error occurred:', errorEvent); }; this.socket.onmessage = (event) => { let message = JSON.parse(event.data); this.messages.push(message); // 将接收到的消息存入数组以便后续展示 }; this.socket.onclose = function(closeEvent){ console.warn(`Connection closed (${closeEvent.code}): ${closeEvent.reason}`); } }, sendMessage(msgContent) { if(this.socket.readyState === WebSocket.OPEN){ try{ this.socket.send(JSON.stringify({content: msgContent})); }catch(e){ console.error("Failed sending message:", e.message); } }else{ alert("Socket connection is not open."); } } }, beforeDestroy(){ this.socket.close(); // 销毁前关闭socket连接 } }); ``` 这段代码展示了如何在一个简单的 Vue 组件内设置 WebSocket 客户端[^1]。通过监听不同的事件(打开、错误、消息接收以及关闭),可以根据应用程序的需求处理各种情况下的逻辑响应。此外还定义了一个发送消息的方法 `sendMessage()` 和确保当组件销毁时正确地断开 WebSocket 连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值