DolphinDB WebSocket接入:实时数据流

目录

    • 摘要
    • 一、WebSocket概述
      • [1.1 什么是WebSocket](#1.1 什么是WebSocket)
      • [1.2 WebSocket vs HTTP](#1.2 WebSocket vs HTTP)
      • [1.3 适用场景](#1.3 适用场景)
    • [二、DolphinDB WebSocket](#二、DolphinDB WebSocket)
      • [2.1 创建WebSocket服务](#2.1 创建WebSocket服务)
      • [2.2 连接管理](#2.2 连接管理)
    • 三、实时数据接收
      • [3.1 连接WebSocket](#3.1 连接WebSocket)
      • [3.2 发送数据](#3.2 发送数据)
      • [3.3 批量发送](#3.3 批量发送)
    • 四、消息处理
      • [4.1 消息格式](#4.1 消息格式)
      • [4.2 消息处理函数](#4.2 消息处理函数)
    • 五、心跳保活
      • [5.1 心跳机制](#5.1 心跳机制)
      • [5.2 服务端心跳响应](#5.2 服务端心跳响应)
    • 六、断线重连
      • [6.1 自动重连](#6.1 自动重连)
      • [6.2 数据缓冲](#6.2 数据缓冲)
    • 七、实战案例
      • [7.1 实时监控数据推送](#7.1 实时监控数据推送)
    • 八、总结
    • 参考资料

摘要

本文深入讲解DolphinDB WebSocket接入技术。从WebSocket协议原理到连接管理,从实时数据接收到消息处理,从心跳保活到断线重连,全面介绍WebSocket数据接入的核心方法。通过丰富的代码示例,帮助读者掌握实时数据流处理的核心技能。


一、WebSocket概述

1.1 什么是WebSocket

WebSocket是全双工实时通信协议:
#mermaid-svg-Ultmphfbe6oaaeZL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ultmphfbe6oaaeZL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ultmphfbe6oaaeZL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ultmphfbe6oaaeZL .error-icon{fill:#552222;}#mermaid-svg-Ultmphfbe6oaaeZL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ultmphfbe6oaaeZL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ultmphfbe6oaaeZL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ultmphfbe6oaaeZL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ultmphfbe6oaaeZL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ultmphfbe6oaaeZL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ultmphfbe6oaaeZL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ultmphfbe6oaaeZL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ultmphfbe6oaaeZL .marker.cross{stroke:#333333;}#mermaid-svg-Ultmphfbe6oaaeZL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ultmphfbe6oaaeZL p{margin:0;}#mermaid-svg-Ultmphfbe6oaaeZL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ultmphfbe6oaaeZL .cluster-label text{fill:#333;}#mermaid-svg-Ultmphfbe6oaaeZL .cluster-label span{color:#333;}#mermaid-svg-Ultmphfbe6oaaeZL .cluster-label span p{background-color:transparent;}#mermaid-svg-Ultmphfbe6oaaeZL .label text,#mermaid-svg-Ultmphfbe6oaaeZL span{fill:#333;color:#333;}#mermaid-svg-Ultmphfbe6oaaeZL .node rect,#mermaid-svg-Ultmphfbe6oaaeZL .node circle,#mermaid-svg-Ultmphfbe6oaaeZL .node ellipse,#mermaid-svg-Ultmphfbe6oaaeZL .node polygon,#mermaid-svg-Ultmphfbe6oaaeZL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ultmphfbe6oaaeZL .rough-node .label text,#mermaid-svg-Ultmphfbe6oaaeZL .node .label text,#mermaid-svg-Ultmphfbe6oaaeZL .image-shape .label,#mermaid-svg-Ultmphfbe6oaaeZL .icon-shape .label{text-anchor:middle;}#mermaid-svg-Ultmphfbe6oaaeZL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Ultmphfbe6oaaeZL .rough-node .label,#mermaid-svg-Ultmphfbe6oaaeZL .node .label,#mermaid-svg-Ultmphfbe6oaaeZL .image-shape .label,#mermaid-svg-Ultmphfbe6oaaeZL .icon-shape .label{text-align:center;}#mermaid-svg-Ultmphfbe6oaaeZL .node.clickable{cursor:pointer;}#mermaid-svg-Ultmphfbe6oaaeZL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Ultmphfbe6oaaeZL .arrowheadPath{fill:#333333;}#mermaid-svg-Ultmphfbe6oaaeZL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ultmphfbe6oaaeZL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ultmphfbe6oaaeZL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ultmphfbe6oaaeZL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Ultmphfbe6oaaeZL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ultmphfbe6oaaeZL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Ultmphfbe6oaaeZL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ultmphfbe6oaaeZL .cluster text{fill:#333;}#mermaid-svg-Ultmphfbe6oaaeZL .cluster span{color:#333;}#mermaid-svg-Ultmphfbe6oaaeZL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ultmphfbe6oaaeZL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Ultmphfbe6oaaeZL rect.text{fill:none;stroke-width:0;}#mermaid-svg-Ultmphfbe6oaaeZL .icon-shape,#mermaid-svg-Ultmphfbe6oaaeZL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ultmphfbe6oaaeZL .icon-shape p,#mermaid-svg-Ultmphfbe6oaaeZL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Ultmphfbe6oaaeZL .icon-shape .label rect,#mermaid-svg-Ultmphfbe6oaaeZL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ultmphfbe6oaaeZL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Ultmphfbe6oaaeZL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Ultmphfbe6oaaeZL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} WebSocket架构
客户端
WebSocket连接
服务端

DolphinDB
特点
全双工
实时推送
长连接

1.2 WebSocket vs HTTP

特性 HTTP WebSocket
通信方式 半双工 全双工
连接 短连接 长连接
实时性 轮询 实时推送
开销

1.3 适用场景

场景 说明
实时监控 实时数据推送
告警通知 实时告警推送
仪表盘 实时数据展示
设备控制 实时指令下发

二、DolphinDB WebSocket

2.1 创建WebSocket服务

python 复制代码
// 创建WebSocket服务
// DolphinDB内置WebSocket支持

// 创建流表接收数据
share streamTable(1:0, 
    `device_id`timestamp`temperature`humidity,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE]) as ws_stream

// WebSocket端点
// ws://localhost:8848/ws

2.2 连接管理

python 复制代码
// WebSocket连接配置
config = dict(STRING, ANY, [
    ["maxConnections", 1000],
    ["heartbeatInterval", 30000],
    ["maxMessageSize", 1048576]
])

三、实时数据接收

3.1 连接WebSocket

javascript 复制代码
// JavaScript客户端示例
const ws = new WebSocket('ws://localhost:8848/ws');

ws.onopen = function() {
    console.log('WebSocket连接成功');
    // 订阅主题
    ws.send(JSON.stringify({
        action: 'subscribe',
        topic: 'sensor/data'
    }));
};

ws.onmessage = function(event) {
    const data = JSON.parse(event.data);
    console.log('收到数据:', data);
};

ws.onerror = function(error) {
    console.error('WebSocket错误:', error);
};

ws.onclose = function() {
    console.log('WebSocket连接关闭');
};

3.2 发送数据

javascript 复制代码
// 发送数据到DolphinDB
function sendData(data) {
    ws.send(JSON.stringify({
        action: 'write',
        table: 'ws_stream',
        data: data
    }));
}

// 示例
sendData({
    device_id: 'D001',
    timestamp: new Date().toISOString(),
    temperature: 25.5,
    humidity: 50.0
});

3.3 批量发送

javascript 复制代码
// 批量发送数据
function sendBatch(dataList) {
    ws.send(JSON.stringify({
        action: 'write',
        table: 'ws_stream',
        data: dataList
    }));
}

// 示例
const batch = [];
for (let i = 0; i < 100; i++) {
    batch.push({
        device_id: `D${i.toString().padStart(3, '0')}`,
        timestamp: new Date().toISOString(),
        temperature: 20 + Math.random() * 10,
        humidity: 40 + Math.random() * 20
    });
}
sendBatch(batch);

四、消息处理

4.1 消息格式

python 复制代码
// JSON消息格式
{
    "action": "write",     // 操作类型
    "table": "ws_stream",  // 目标表
    "data": {              // 数据
        "device_id": "D001",
        "timestamp": "2024-01-01T00:00:00",
        "temperature": 25.5,
        "humidity": 50.0
    }
}

// 订阅消息
{
    "action": "subscribe",
    "topic": "sensor/data"
}

// 查询消息
{
    "action": "query",
    "sql": "select * from ws_stream limit 10"
}

4.2 消息处理函数

python 复制代码
// 消息处理函数
def handleWsMessage(msg) {
    action = msg.action
    
    if (action == "write") {
        // 写入数据
        table = msg.table
        data = msg.data
        // 写入逻辑
    } else if (action == "subscribe") {
        // 订阅主题
        topic = msg.topic
        // 订阅逻辑
    } else if (action == "query") {
        // 查询数据
        sql = msg.sql
        // 查询逻辑
    }
}

五、心跳保活

5.1 心跳机制

javascript 复制代码
// 客户端心跳
let heartbeatInterval;

function startHeartbeat() {
    heartbeatInterval = setInterval(() => {
        if (ws.readyState === WebSocket.OPEN) {
            ws.send(JSON.stringify({ action: 'ping' }));
        }
    }, 30000);  // 每30秒发送心跳
}

function stopHeartbeat() {
    clearInterval(heartbeatInterval);
}

ws.onopen = function() {
    startHeartbeat();
};

ws.onclose = function() {
    stopHeartbeat();
};

5.2 服务端心跳响应

python 复制代码
// 服务端心跳处理
def handleHeartbeat(conn) {
    // 收到ping,返回pong
    ws::send(conn, {action: "pong", timestamp: now()})
}

六、断线重连

6.1 自动重连

javascript 复制代码
// 自动重连机制
let ws;
let reconnectAttempts = 0;
const maxReconnectAttempts = 5;

function connect() {
    ws = new WebSocket('ws://localhost:8848/ws');
    
    ws.onopen = function() {
        console.log('WebSocket连接成功');
        reconnectAttempts = 0;
    };
    
    ws.onclose = function() {
        console.log('WebSocket连接关闭');
        if (reconnectAttempts < maxReconnectAttempts) {
            reconnectAttempts++;
            console.log(`尝试重连 (${reconnectAttempts}/${maxReconnectAttempts})`);
            setTimeout(connect, 3000);
        }
    };
    
    ws.onerror = function(error) {
        console.error('WebSocket错误:', error);
    };
}

connect();

6.2 数据缓冲

javascript 复制代码
// 断线时缓冲数据
const dataBuffer = [];
const maxBufferSize = 10000;

function sendDataWithBuffer(data) {
    if (ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify(data));
        // 发送缓冲数据
        while (dataBuffer.length > 0) {
            ws.send(JSON.stringify(dataBuffer.shift()));
        }
    } else {
        // 缓冲数据
        if (dataBuffer.length < maxBufferSize) {
            dataBuffer.push(data);
        }
    }
}

七、实战案例

7.1 实时监控数据推送

python 复制代码
// ========== 实时监控数据推送 ==========

// 1. 创建流表
share streamTable(100000:0, 
    `device_id`timestamp`temperature`humidity`pressure,
    [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE]) as monitor_stream

// 2. 启用持久化
enableTablePersistence(monitor_stream, true, true, 1000000)

// 3. 创建分布式表
db = database("dfs://ws_db", VALUE, 1..1000)
schema = table(1:0, `device_id`timestamp`temperature`humidity`pressure,
               [SYMBOL, TIMESTAMP, DOUBLE, DOUBLE, DOUBLE])
db.createPartitionedTable(schema, `monitor_data, `device_id)

// 4. 订阅写入
subscribeTable(, "monitor_stream", "persist", -1,
    def(msg) {
        loadTable("dfs://ws_db", "monitor_data").append!(msg)
    }, 10000, 5000)

// 5. WebSocket端点
// ws://localhost:8848/ws

// 6. 客户端示例(JavaScript)
/*
const ws = new WebSocket('ws://localhost:8848/ws');

ws.onopen = function() {
    console.log('连接成功');
};

function pushData(deviceId, temp, humid, press) {
    ws.send(JSON.stringify({
        action: 'write',
        table: 'monitor_stream',
        data: {
            device_id: deviceId,
            timestamp: new Date().toISOString(),
            temperature: temp,
            humidity: humid,
            pressure: press
        }
    }));
}
*/

print("实时监控数据推送系统已就绪")

八、总结

本文详细介绍了DolphinDB WebSocket接入:

  1. WebSocket原理:全双工、实时推送、长连接
  2. 连接管理:创建连接、配置参数
  3. 数据接收:连接、发送、批量发送
  4. 消息处理:消息格式、处理函数
  5. 心跳保活:心跳机制、响应处理
  6. 断线重连:自动重连、数据缓冲

思考题

  1. WebSocket相比HTTP有什么优势?
  2. 如何设计可靠的WebSocket连接?
  3. 如何处理WebSocket断线问题?

参考资料


相关推荐
zhao32668575115 小时前
静态IP代理固定IP与动态IP的根本差异,账号操作安全性如何体现
网络·网络协议·tcp/ip
淼澄研学21 小时前
Kimi API黑产倒卖技术解析与Python合规接入指南
开发语言·网络·python
SendTomo1 天前
P2P文件传输工具对比:SendTomo vs send.wang
javascript·网络协议·webrtc·html5·p2p
qyyyyy5701 天前
英文技术标准和协议规范怎么读?RFC、接口规范与安全标准 PDF 翻译流程
网络协议·网络安全·机器翻译·csrf·技术美术
无锡耐特森1 天前
Profinet转ModbusTCP协议网关:数字化工厂跨协议互联
网络
MartinYeung51 天前
[论文学习]ProAct:针对LLM越狱的主动防禦框架
网络·学习·安全
发量惊人的中年网工1 天前
中小企业网络管理进阶:从设备堆叠到统一管理
服务器·网络·安全·网络安全·php·制造
workflower1 天前
案例 :某交通厅基于AI技术的智能安全运营实践
网络·人工智能·安全·设计模式·机器人
SendTomo1 天前
WebRTC文件互传工具实测对比
javascript·网络·webrtc·html5·p2p
运维全栈笔记1 天前
致远 OA HTTPS 配置避坑指南
网络协议·http·https