整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

WebSocket技术入门:JavaScript实战详解

WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许客户端与服务器之间进行实时、双向的数据传输。它极大地改善了传统HTTP请求-响应模式下延迟和效率的问题,特别适合于实时应用如聊天室、协同编辑、股票报价等场景。本文将通过一个完整的JavaScript示例,带领读者快速入门WebSocket技术。

目标

  1. 了解WebSocket基本概念
  2. 学习如何创建WebSocket客户端
  3. 掌握WebSocket事件处理方法
  4. 实现简单的WebSocket消息发送和接收

WebSocket基础概念

WebSocket是基于HTTP协议升级机制建立起来的一种持久化的TCP连接。客户端通过ws://(非加密)或wss://(加密,即HTTPS)协议发起握手请求,并在成功升级后保持长连接状态。在此连接之上,客户端和服务端可以自由地互相发送数据帧,无需像HTTP那样每次发送都新建连接。

创建WebSocket客户端

在JavaScript中,我们可以通过构造函数WebSocket来创建一个新的WebSocket对象:

var socket = new WebSocket('ws://yourserver.com/ws-endpoint');

这里的ws://yourserver.com/ws-endpoint是WebSocket服务器的地址和端点,替换为实际的服务地址即可。

WebSocket事件处理

WebSocket对象提供了多个事件处理方法,用于监听连接的状态变化以及数据交互:

socket.onopen = function(event) {
    console.log('Connection open!');
};

socket.onmessage = function(event) {
    console.log('Received message:', event.data);
    // 对接收到的消息进行处理,例如更新UI
};

socket.onerror = function(error) {
    console.error('Error occurred:', error);
};

socket.onclose = function(event) {
    console.log('Connection closed with code: ' + event.code + ', reason: ' + event.reason);
};
  • onopen:当连接成功建立时触发。
  • onmessage:每当从服务器接收到新消息时触发,事件对象的data属性包含接收到的数据。
  • onerror:当发生错误时触发,如网络问题或者服务器返回错误等。
  • onclose:当连接关闭时触发,提供关闭原因代码和关闭理由。

发送和接收消息

在WebSocket连接建立后,可以使用send()方法向服务器发送数据:

// 发送文本消息到服务器
socket.send('Hello, Server!');

// 或者发送JSON格式数据
var data = { message: 'Some data', sender: 'Client' };
socket.send(JSON.stringify(data));

同时,在服务器返回消息时,onmessage处理器会捕获并处理这些消息。

完整示例

下面是一个简单的HTML页面上的WebSocket客户端实现:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Example</title>
</head>
<body>
    <script>
        var socket = new WebSocket('ws://yourserver.com/ws-endpoint');

        socket.onopen = function(event) {
            console.log('WebSocket connection opened.');
            socket.send('Client connected');
        };

        socket.onmessage = function(event) {
            console.log('Received message:', event.data);
            // 在此处添加对消息的实际处理逻辑,例如显示在页面上
        };

        socket.onerror = function(error) {
            console.error('WebSocket error:', error);
        };

        socket.onclose = function(event) {
            console.log('WebSocket connection closed with code: ' + event.code + ', reason: ' + event.reason);
        };
    </script>
</body>
</html>

以上就是使用JavaScript构建WebSocket客户端的基本过程。为了实现完整的通讯功能,还需要在服务器端设置WebSocket服务来接收和响应客户端的消息。这通常可以通过Node.js的ws库或其他后端框架(如Spring Boot、Java EE)提供的WebSocket支持来完成。

、JavaScript 写得websocket html主要代码如下图,详细代码在最下边:




运行效果如下:

、使用跨文档消息传递(Cross-document Messaging)

可以在不同窗口或iframe之间安全地传递消息,即使这些窗口或iframe来自不同的域。以下是使用window.postMessage()方法进行跨域消息传递的基本示例:

假设有两个页面:page1.html和page2.html,它们分别位于不同的域。

在page1.html中,我们想要向page2.html发送消息:

<!-- page1.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Page 1</title>
</head>
<body>
    <button id="sendMessageBtn">Send Message to Page 2</button>

    <script>
        const sendMessageBtn = document.getElementById('sendMessageBtn');

        // 监听按钮点击事件
        sendMessageBtn.addEventListener('click', function() {
            // 获取目标窗口的引用
            const targetWindow = window.parent.frames['page2-frame'];

            // 向目标窗口发送消息
            targetWindow.postMessage('Hello from Page 1!', 'http://www.example.com/page2.html');
        });
    </script>
</body>
</html>

在page2.html中,我们接收来自page1.html的消息:

<!-- page2.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Page 2</title>
</head>
<body>
    <iframe src="http://www.example.com/page1.html" name="page1-frame" id="page1-frame"></iframe>

    <script>
        // 监听来自其他窗口的消息
        window.addEventListener('message', function(event) {
            // 判断消息来源是否是预期的域
            if (event.origin === 'http://www.example.com') {
                // 处理收到的消息
                console.log('Received message from Page 1:', event.data);
            }
        });
    </script>
</body>
</html>

page1.html包含一个按钮,当点击按钮时,会向page2.html发送消息。page2.html中通过监听window对象的message事件来接收来自page1.html的消息,并且只有当消息的来源是预期的域时才会处理该消息。

需要注意的是,跨文档消息传递仅在现代浏览器中得到支持,且需要发送消息的窗口或iframe引用以及目标窗口的域。以前的IE浏览器啥的是不支持的。这种方式较为简单,方便初学者进行测试。

二、还有一种办法较为复杂,可以利用代理服务器,通过在同一域下设置一个代理服务器,将跨域请求发送到该代理服务器上,再由代理服务器转发请求到目标服务器。这种方法需要在服务器端实现代理,但可以绕过浏览器的跨域限制。

另外还有两种较为简单的方式也做一下介绍,下面这2种方式是常用的方式了,较为简单,

三、JSONP(JSON with Padding):JSONP是一种利用<script>标签的GET请求实现跨域数据传输的技术。它允许从其他域加载数据,但只支持GET请求,且需要目标服务器支持返回JavaScript回调函数。JSONP的缺点是安全性较低,仅能进行GET请求。

四、CORS(Cross-Origin Resource Sharing):CORS是一种现代的跨域资源共享机制,它允许服务器端设置HTTP头部,以允许在不同域之间的安全数据传输。通过在服务器端配置,可以允许跨域请求发送和接收数据。

五、WebSocket:得利于HTML5技术的发展,现在主流浏览器的支持,WebSocket是HTML5提供的一种在单个TCP连接上进行全双工通讯的协议,它可以与任意域的服务器进行通讯,但需要服务器端支持WebSocket协议。

在客户端,我们可以使用JavaScript来创建WebSocket连接:

// 客户端代码
const socket = new WebSocket('ws://example.com:8080'); // 替换为实际的WebSocket服务器地址

// 当WebSocket连接成功建立时触发
socket.onopen = function(event) {
    console.log('WebSocket连接已建立');
    
    // 向服务器发送数据
    socket.send('Hello from client!');
};

// 当接收到来自服务器的消息时触发
socket.onmessage = function(event) {
    console.log('Received message from server:', event.data);
};

// 当发生错误时触发
socket.onerror = function(error) {
    console.error('WebSocket发生错误:', error);
};

// 当WebSocket连接关闭时触发
socket.onclose = function(event) {
    console.log('WebSocket连接已关闭');
};

在服务器端,您需要使用相应的语言和框架来创建WebSocket服务器。以下是一个简单的Node.js示例: