Skip to content

WebSocket

问客服要测试域名

第一步:连接后发送 key:你的密钥:国家 id

发送示例:ws.send("key:你的密钥:14") 身份验证成功成功后会返回 身份验证成功 字符串

第二步:10s 一次心跳 发送 heartbeat

发送示例:ws.send("heartbeat") 心跳发送成功后会返回 pong 字符串

Example Response

json
{
  "Id": 535578685, // 股票Id 也是股票的pid
  "Symbol": "HPAL", // 股票编码
  "Name": "HP ADHESIVES LTD", // 股票名称
  "Last": 84.11, // 股票最新价格
  "Low": 82.92, // 最低
  "High": 85.5, // 最高
  "Open": 84.83, // 今开
  "PrevClose": 83.59, // 昨收
  "Time": 1733306481, // 价格更新时间
  "Volume": 93634, // 交易量
  "Chg": 0.52, // 涨幅
  "ChgPct": 0.62, // 涨幅率
  "type": "NSE", // 股票所在的交易所
  "Ratio": "37.33", // 市盈率
  "MarketCap": "7.69B", // 市值
  "Eps": "2.24", // 每股收益
  "Bid": 84.11, // 买进价
  "Ask": 0, // 卖出价
  "Beta": 0.722934, // 贝塔
  "country_id": 14 // 国家Id
}

DEMO

java

// 下面是示例代码和包版本
// <dependencies>
//         <dependency>
//             <groupId>org.java-websocket</groupId>
//             <artifactId>Java-WebSocket</artifactId>
//             <version>1.3.5</version>
//         </dependency>
//         <dependency>
//             <groupId>org.json</groupId>
//             <artifactId>json</artifactId>
//             <version>20220924</version>
//         </dependency>
// </dependencies>

package com.client;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONObject;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Timer;
import java.util.TimerTask;
public class WebSocketClientExample {
    public static void main(String[] args) {
        try {
            URI uri = new URI("ws://ws.com"); // 替换为实际的 WebSocket 地址
            String key = "key:你的密钥:国家id"; // 替换为实际密钥和国家id
            WebSocketClient client = new WebSocketClient(uri) {
                private Timer heartbeatTimer;
                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    System.out.println("已连接到服务器");
                    send(key);
                    // 启动心跳定时器
                    heartbeatTimer = new Timer();
                    heartbeatTimer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            send("heartbeat");
                        }
                    }, 0, 3000); // 每3秒发送一次心跳消息
                }
                @Override
                public void onMessage(String message) {
                    // 获取当前时间并格式化为字符串
                    LocalDateTime now = LocalDateTime.now();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    String timestamp = now.format(formatter);
                    try {
                        if (message.contains("身份验证成功") || message.contains("pong") || message.contains("身份验证失败")) {
                            System.out.println(timestamp + "" + message);
                            return;
                        }
                        JSONObject json = new JSONObject(message);
                        String pid = json.optString("pid");
                        String last = json.optString("last");
                        // 输出 pid 和 last
                        // System.out.println(timestamp + " pid: " + pid + "价格: " + last);
                    } catch (Exception e) {
                        System.err.println("处理消息时发生错误: " + message);
                    }
                }
                @Override
                public void onClose(int code, String reason, boolean remote) {
                    System.out.println("连接关闭: " + reason);
                    if (heartbeatTimer != null) {
                        heartbeatTimer.cancel(); // 取消心跳定时器
                    }
                    // 尝试重新连接
                    try {
                        System.out.println("尝试重新连接...");
                        Thread.sleep(10000); // 10秒后尝试重新连接
                        connect(); // 重新连接
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                @Override
                public void onError(Exception ex) {
                    System.err.println("发生错误: " + ex.getMessage());
                }
            };
            client.connect();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }
}
php
// 测试环境 php7.4.33 composer 2.7.6
// 使用 composer 安装必要的依赖
// composer require textalk/websocket
// composer require react/event-loop
// composer require react/promise

<?php

require 'vendor/autoload.php';
use WebSocket\Client;
use React\EventLoop\Factory;
use React\Promise\Deferred;
$url = "ws://test.com";
$heartbeatInterval = null; // 声明心跳定时器变量
$ws = null; // WebSocket 客户端
function open($ws, $loop) {
    global $heartbeatInterval; // 引用全局变量
    try {
        // 发送包含key的消息进行身份验证
        $ws->send('key:你的密钥:国家id');
        echo "已连接到服务器\n";
        // 定义心跳定时器
        $heartbeatInterval = $loop->addPeriodicTimer(3, function () use ($ws) {
            try {
                $ws->send('heartbeat');
            } catch (Exception $e) {
                echo "发送心跳失败:{$e->getMessage()}\n";
            }
        });
    } catch (Exception $e) {
        echo "身份验证失败:{$e->getMessage()}\n";
    }
}
function reconnect($loop, $url) {
    global $ws, $heartbeatInterval; // 引用全局变量
    if ($heartbeatInterval !== null) {
        $loop->cancelTimer($heartbeatInterval); // 停止心跳定时器
        $heartbeatInterval = null;
    }
    if ($ws !== null) {
        try {
            $ws->close(); // 尝试关闭之前的连接
        } catch (Exception $e) {
            echo "关闭连接失败:{$e->getMessage()}\n";
        }
        $ws = null;
    }
    echo "尝试重新连接...\n";
    $loop->addTimer(10, function () use ($loop, $url) { // 10秒后尝试重新连接
        global $ws;
        try {
            $ws = new Client($url, ['timeout' => 10]); // 增加读取超时时间
            open($ws, $loop); // 打开新连接
        } catch (Exception $e) {
            echo "重新连接失败:{$e->getMessage()}\n";
            reconnect($loop, $url); // 如果连接失败,递归调用重新连接
        }
    });
}
// 异步处理接收到的数据
function processData($message) {
    $deferred = new Deferred();
    // 模拟异步处理,这里可以是任何异步任务
    $deferred->resolve("处理数据: {$message}");
    return $deferred->promise();
}
$loop = Factory::create();
$ws = new Client($url, ['timeout' => 10]); // 初始连接
open($ws, $loop);
// 使用 ReactPHP 的定时器来处理 WebSocket 消息
$loop->addPeriodicTimer(0, function () use ($loop, $url) {
    global $ws, $heartbeatInterval; // 引用全局变量
    try {
        if ($ws !== null) {
            $message = $ws->receive();
            if ($message !== null) {
                echo "收到服务器消息: {$message}\n";
                // 异步处理接收到的数据
                processData($message)->then(function ($result) {
                    echo "{$result}\n";
                });
            }
        }
    } catch (WebSocket\ConnectionException $e) {
        echo "WebSocket 连接错误:{$e->getMessage()}\n";
        // 特定处理Bad opcode错误
        if (strpos($e->getMessage(), 'Bad opcode') !== false) {
            echo "接收到无效的操作码,重新连接...\n";
            reconnect($loop, $url);
        } else {
            reconnect($loop, $url);
        }
    } catch (Exception $e) {
        echo "发生错误:{$e->getMessage()}\n";
        // 连接断开,尝试重新连接
        reconnect($loop, $url);
    }
});
// 运行事件循环
$loop->run();
javascript
const WebSocket = require("ws");
let ws = new WebSocket(url);
function open() {
  // 发送包含key的消息进行身份验证
  ws.send("key:你的密钥:国家id");
  // 发送心跳消息以保持连接
  console.log("已连接到服务器");
  heartbeatInterval = setInterval(function () {
    ws.send("heartbeat");
  }, 1000 * 3); // 每3秒发送一次心跳消息
}
ws.onopen = open;
ws.onmessage = async function (event) {
  console.log("收到服务器消息", event.data);
  // 在这里处理从服务器接收到的消息
};
ws.onclose = function (e) {
  clearInterval(heartbeatInterval); // 清除心跳定时器
  // 尝试重新连接
  setTimeout(function () {
    console.log("尝试重新连接...", e);
    const newWs = new WebSocket(url);
    newWs.onopen = function () {
      console.log("重新连接成功");
      ws = newWs; // 更新ws对象为新的WebSocket对象
      open();
    };
    newWs.onmessage = ws.onmessage;
    newWs.onclose = ws.onclose;
    newWs.onerror = ws.onerror;
  }, 1000 * 10); // 3秒后尝试重新连接
};
ws.onerror = function (error) {
  console.error("发生错误:", error);
};

接口禁止二次分发,限个人开发者使用,接口仅供学习研究禁止涉及非法业务。