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);
};