闪电快报
闪电快报为专线接口产品,提供全球闪电定位数据的低延迟 REST 查询与 WebSocket 推送服务。开通专线接口应用后即可使用,与机场快报等专线产品共享同一套配额。
产品说明
| 项目 | 说明 |
|---|---|
| 时效性 | 近实时;REST 可查最近 1~5 分钟,WebSocket 每秒批量推送 |
| 数据范围 | 仅近期分钟桶数据,不支持任意时段历史回溯 |
| 协议 | HTTP REST + WebSocket 推送 |
| SLA | 99.9% 可用性保障(与机场快报等同属专线产品池) |
| 计费 | 按时长订阅 |
推荐对接方式
先用 REST(建议 minutes=5)拉取当前窗口,再连接 WebSocket 订阅增量;连上后不会回放历史。无数据时仍返回 HTTP 200,见下方空数据规则。
REST Base URL
https://special.data-api.skyviewor.host/fast-lightning
WebSocket Endpoint
wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes
鉴权
闪电快报沿用开发者 API 通用鉴权方式,支持 API Key 直接鉴权和 Token 鉴权两种模式,两种模式最终效果相同,调用同一个数据接口。
API Key 直接鉴权
与标准接口一致,在 Authorization Header 中携带 Bearer <API Key> 即可直接调用数据接口:
Authorization: Bearer sk-d5d0542bef7e42e2b8909cb7f42af5fb
Token 鉴权
Token 鉴权通过「先换取临时令牌再调用」的方式,进一步降低 API Key 在网络传输中的泄露风险。流程如下:
- 用 API Key 换取临时数据令牌(有效期 5 分钟)
- 用令牌调用数据接口或建立 WebSocket 连接
换取到的 ft- 令牌可通过以下任一方式调用数据接口(效果相同):
- Header:
Authorization: Bearer ft-xxx - Query:
?token=ft-xxx(浏览器 WebSocket 等无法自定义 Header 的场景推荐)
获取令牌:
# 更换为您的以 sk- 开头的 API Key 字符串
curl -s \
-H "Authorization: Bearer sk-d5d0542bef7e42e2b8909cb7f42af5fb" \
-X POST "https://special.data-api.skyviewor.host/fast-lightning/auth/token"
import json, urllib.request
API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb" # 更换为您的以 sk- 开头的 API Key 字符串
req = urllib.request.Request(
"https://special.data-api.skyviewor.host/fast-lightning/auth/token",
method="POST",
headers={"Authorization": f"Bearer {API_KEY}"},
)
with urllib.request.urlopen(req, timeout=30) as resp:
token_data = json.loads(resp.read().decode())
print(token_data["token"]) # ft-...
const API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
const resp = await fetch("https://special.data-api.skyviewor.host/fast-lightning/auth/token", {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { token } = await resp.json();
console.log(token); // ft-...
const API_KEY: string = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
const resp = await fetch("https://special.data-api.skyviewor.host/fast-lightning/auth/token", {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { token }: { token: string } = await resp.json();
console.log(token); // ft-...
apiKey := "sk-d5d0542bef7e42e2b8909cb7f42af5fb" // 更换为您的以 sk- 开头的 API Key 字符串
req, _ := http.NewRequest("POST", "https://special.data-api.skyviewor.host/fast-lightning/auth/token", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var tokenData map[string]interface{}
json.Unmarshal(body, &tokenData)
fmt.Println(tokenData["token"])
String API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://special.data-api.skyviewor.host/fast-lightning/auth/token"))
.header("Authorization", "Bearer " + API_KEY)
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
var apiKey = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");
var json = await client.PostAsync("https://special.data-api.skyviewor.host/fast-lightning/auth/token", null);
Console.WriteLine(await json.Content.ReadAsStringAsync());
$API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
$ch = curl_init("https://special.data-api.skyviewor.host/fast-lightning/auth/token");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer {$API_KEY}"]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
echo $result['token'] . "\n";
令牌返回格式:
{
"token": "ft-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"expires_at": "2026-07-13T13:41:00+00:00"
}
使用示例(REST):
Authorization: Bearer ft-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
或:
GET .../rest/strikes?token=ft-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
RESTful 接口
闪电定位查询
查询最近若干分钟内的闪电定位记录(按分钟桶聚合)。
| 项目 | 内容 |
|---|---|
| 方法 | GET |
| 路径 | https://special.data-api.skyviewor.host/fast-lightning/rest/strikes |
请求参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
minutes |
int | 否 | 1 |
查询最近 N 分钟,取值范围 1~5 |
token |
string | 否 | — | 短期 Token(Query);亦可使用 Header Authorization: Bearer ft-xxx |
空数据规则
- 不传
minutes时默认查最近 1 分钟。 - 任意
minutes(1~5)且无数据时均返回 HTTP 200,count为0,data为空数组[]。
有数据时的响应示例
{
"minutes": 1,
"from": "2026-07-13T13:36:00+00:00",
"to": "2026-07-13T13:36:45+00:00",
"checked_at": "2026-07-13T13:36:45+00:00",
"count": 42,
"buckets": ["202607131336"],
"data": [
{
"time": 1783949760123456000,
"obser_datetime": "2026-07-13T13:36:00.123456+00:00",
"lat": 39.9042,
"lon": 116.4074,
"alt": 0,
"pol": -1,
"mds": 1234,
"mcg": 54,
"status": 0,
"region": 3,
"arrived_at": "2026-07-13T13:36:00.456789+00:00"
}
]
}
无数据时的响应示例(HTTP 200)
{
"minutes": 1,
"from": "2026-07-13T13:36:00+00:00",
"to": "2026-07-13T13:36:45+00:00",
"checked_at": "2026-07-13T13:36:45+00:00",
"count": 0,
"buckets": ["202607131336"],
"data": []
}
响应字段(顶层)
| 字段 | 类型 | 说明 |
|---|---|---|
minutes |
int | 实际查询的分钟数 |
from |
string | 查询时间窗起点(UTC,ISO 8601) |
to |
string | 查询时间窗终点(UTC,ISO 8601) |
checked_at |
string | 服务端处理本请求的时间(UTC) |
count |
int | 返回的闪电条数 |
buckets |
array | 本次读取的分钟桶后缀列表,格式 YYYYMMDDHHMM(UTC) |
data |
array | 闪电记录列表,字段含义见下表 |
闪电记录字段说明
每条 data[] 记录对应一次闪电解译结果,字段含义如下:
| 字段 | 类型 | 单位 | 说明 |
|---|---|---|---|
time |
int | ns | 闪电发生时间,Unix 纳秒时间戳 |
obser_datetime |
string | — | 由 time 转换的观测时间(UTC,ISO 8601);字段名为 obser_datetime |
lat |
float | ° | 落点纬度(北纬为正),WGS84 |
lon |
float | ° | 落点经度(东经为正),WGS84 |
alt |
float | m | 高度;常为 0 |
pol |
int | — | 极性:一般 -1 / +1,0 多为未知 |
mds |
int | ns | 最大时间偏差;越小通常定位越好 |
mcg |
int | ° | 探测站覆盖角度间隙;实测多为整数,越小通常几何越好 |
status |
int | — | 状态 / 质量标记 |
region |
int | — | 网络区域编号 |
arrived_at |
string | — | 本服务入库时间(UTC,ISO 8601) |
字段说明
lat / lon 为 WGS84 经纬度。业务一般以坐标与时间字段为主,mds / mcg 可作质量参考。响应中可能含 delay、lonc、latc 等扩展字段,以本表为准;不返回 sig(探测站明细)。接口不支持按 region 或地理范围过滤。
代码示例
# 更换为您的以 sk- 开头的 API Key 字符串
# 方式一:API Key 直接鉴权(默认最近 1 分钟)
curl -s \
-H "Authorization: Bearer sk-d5d0542bef7e42e2b8909cb7f42af5fb" \
"https://special.data-api.skyviewor.host/fast-lightning/rest/strikes"
# 查询最近 5 分钟
curl -s \
-H "Authorization: Bearer sk-d5d0542bef7e42e2b8909cb7f42af5fb" \
"https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5"
# 方式二:Token 鉴权(先换取 ft- 令牌)
curl -s -X POST \
-H "Authorization: Bearer sk-d5d0542bef7e42e2b8909cb7f42af5fb" \
"https://special.data-api.skyviewor.host/fast-lightning/auth/token"
# Header 传 Token
curl -s \
-H "Authorization: Bearer <TOKEN>" \
"https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5"
# 或 Query 传 Token
curl -s "https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5&token=<TOKEN>"
import json, urllib.request
API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb" # 更换为您的以 sk- 开头的 API Key 字符串
# 方式一:API Key 直接鉴权
url = "https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5"
req = urllib.request.Request(url, headers={"Authorization": f"Bearer {API_KEY}"})
with urllib.request.urlopen(req, timeout=30) as resp:
result = json.loads(resp.read().decode())
# 方式二:Token 鉴权
def get_token():
req = urllib.request.Request(
"https://special.data-api.skyviewor.host/fast-lightning/auth/token",
method="POST",
headers={"Authorization": f"Bearer {API_KEY}"},
)
with urllib.request.urlopen(req, timeout=30) as resp:
return json.loads(resp.read().decode())["token"]
token = get_token()
url = f"https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5&token={token}"
req = urllib.request.Request(url)
with urllib.request.urlopen(req, timeout=30) as resp:
result = json.loads(resp.read().decode())
print(f"共 {result['count']} 条")
for item in result["data"][:5]:
print(f"{item['obser_datetime']} lat={item['lat']} lon={item['lon']} pol={item['pol']}")
const API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
// 方式一:API Key 直接鉴权
let url = "https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5";
let resp = await fetch(url, { headers: { Authorization: `Bearer ${API_KEY}` } });
let result = await resp.json();
// 方式二:Token 鉴权
const tokenResp = await fetch("https://special.data-api.skyviewor.host/fast-lightning/auth/token", {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { token } = await tokenResp.json();
url = `https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5&token=${token}`;
resp = await fetch(url);
result = await resp.json();
console.log(`共 ${result.count} 条`);
for (const item of (result.data || []).slice(0, 5)) {
console.log(`${item.obser_datetime} lat=${item.lat} lon=${item.lon} pol=${item.pol}`);
}
const API_KEY: string = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
let url = "https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5";
let resp = await fetch(url, { headers: { Authorization: `Bearer ${API_KEY}` } });
let result = await resp.json();
const tokenResp = await fetch("https://special.data-api.skyviewor.host/fast-lightning/auth/token", {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { token }: { token: string } = await tokenResp.json();
url = `https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5&token=${token}`;
resp = await fetch(url);
result = await resp.json();
console.log(`共 ${result.count} 条`);
apiKey := "sk-d5d0542bef7e42e2b8909cb7f42af5fb" // 更换为您的以 sk- 开头的 API Key 字符串
req, _ := http.NewRequest("GET",
"https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
String API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5"))
.header("Authorization", "Bearer " + API_KEY)
.GET()
.build();
HttpResponse<String> resp = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
var apiKey = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");
var json = await client.GetStringAsync(
"https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5");
Console.WriteLine(json);
$API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
$ch = curl_init("https://special.data-api.skyviewor.host/fast-lightning/rest/strikes?minutes=5");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer {$API_KEY}"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response . "\n";
WebSocket 推送
闪电快报支持实时推送,连接建立并订阅后无需轮询,每秒批量下发新落点。连接成功后不会回放历史,请先通过 REST 查询拉取时间窗;订阅后为全量推送,不支持按区域过滤。
鉴权方式
| 端点 | 说明 | Token 鉴权 | API Key 直传 |
|---|---|---|---|
wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes |
批量推送闪电记录 | URL Query ?token=ft-xxx,或握手 Header Authorization: Bearer ft-xxx |
WS 握手 Header Authorization: Bearer sk-xxx |
浏览器 WebSocket API 不支持自定义 Header,浏览器场景请用 Query 传 Token。
订阅与取消
客户端发送 JSON 消息控制是否接收推送:
{"action": "subscribe"}
{"action": "unsubscribe"}
{"action": "pong"}
订阅成功后服务端会回复:
{"type": "subscribed"}
取消订阅后服务端会回复:
{"type": "unsubscribed"}
推送消息格式
服务端每秒批量推送,type 为 new_strikes,data 为数组(可能包含 0-N 条闪电记录)。字段含义见 闪电记录字段说明。
{
"type": "new_strikes",
"data": [
{
"time": 1783949760123456000,
"obser_datetime": "2026-07-13T13:36:00.123456+00:00",
"lat": 39.9042,
"lon": 116.4074,
"alt": 0,
"pol": -1,
"mds": 1234,
"mcg": 54,
"status": 0,
"region": 3,
"arrived_at": "2026-07-13T13:36:00.456789+00:00"
}
]
}
心跳与连接管理
// 应用层心跳(每 5 分钟,文本帧 JSON;非 WebSocket 协议层 Ping)
{"type": "ping"}
// 连接即将到期(24 小时到期前 5 分钟通知)
{"type": "server_notice", "message": "连接将在 300 秒后关闭", "remaining_seconds": 300}
客户端收到 ping 后建议回复 {"action": "pong"}。当前实现不会因未及时回复 pong 而主动断开连接;连接关闭仍以时长上限(4008)、连接数超限(4009)等规则为准。
代码示例
import asyncio, json, urllib.request
import websockets
API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb" # 更换为您的以 sk- 开头的 API Key 字符串
# 方式一:API Key 直传(通过 WS 握手 Header)
# 较新 websockets 用 additional_headers;旧版用 extra_headers,按所装版本二选一
async def listen_direct():
url = "wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes"
async with websockets.connect(
url,
additional_headers={"Authorization": f"Bearer {API_KEY}"},
# extra_headers={"Authorization": f"Bearer {API_KEY}"}, # 旧版 websockets
) as ws:
await ws.send(json.dumps({"action": "subscribe"}))
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "new_strikes":
for s in msg["data"]:
print(f"{s['obser_datetime']} lat={s['lat']} lon={s['lon']} pol={s['pol']}")
elif msg["type"] == "ping":
# 应用层心跳(JSON 文本帧),不是 WebSocket 协议层 Ping
await ws.send(json.dumps({"action": "pong"}))
# 方式二:Token 鉴权(先换 Token,再通过 URL query param 连接)
def get_token():
req = urllib.request.Request(
"https://special.data-api.skyviewor.host/fast-lightning/auth/token",
method="POST",
headers={"Authorization": f"Bearer {API_KEY}"},
)
with urllib.request.urlopen(req, timeout=30) as resp:
return json.loads(resp.read().decode())["token"]
async def listen_with_token():
TOKEN = get_token()
url = f"wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes?token={TOKEN}"
async with websockets.connect(url) as ws:
await ws.send(json.dumps({"action": "subscribe"}))
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "new_strikes":
for s in msg["data"]:
print(f"{s['obser_datetime']} lat={s['lat']} lon={s['lon']}")
elif msg["type"] == "ping":
await ws.send(json.dumps({"action": "pong"}))
asyncio.run(listen_direct()) # 或 asyncio.run(listen_with_token())
// 浏览器端 WebSocket API 不支持自定义 Header,请使用 Token 鉴权。
const API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
const tokenResp = await fetch("https://special.data-api.skyviewor.host/fast-lightning/auth/token", {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { token } = await tokenResp.json();
const ws = new WebSocket(`wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes?token=${token}`);
ws.onopen = () => {
ws.send(JSON.stringify({ action: "subscribe" }));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "new_strikes") {
msg.data.forEach(s => {
console.log(`${s.obser_datetime} lat=${s.lat} lon=${s.lon} pol=${s.pol}`);
});
} else if (msg.type === "ping") {
ws.send(JSON.stringify({ action: "pong" }));
}
};
const API_KEY: string = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
const tokenResp = await fetch("https://special.data-api.skyviewor.host/fast-lightning/auth/token", {
method: "POST",
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { token }: { token: string } = await tokenResp.json();
const ws = new WebSocket(`wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes?token=${token}`);
ws.onopen = () => {
ws.send(JSON.stringify({ action: "subscribe" }));
};
ws.onmessage = (event: MessageEvent) => {
const msg = JSON.parse(event.data);
if (msg.type === "new_strikes") {
msg.data.forEach((s: any) => {
console.log(`${s.obser_datetime} lat=${s.lat} lon=${s.lon}`);
});
} else if (msg.type === "ping") {
ws.send(JSON.stringify({ action: "pong" }));
}
};
apiKey := "sk-d5d0542bef7e42e2b8909cb7f42af5fb" // 更换为您的以 sk- 开头的 API Key 字符串
dialer := websocket.DefaultDialer
reqHeader := http.Header{}
reqHeader.Set("Authorization", "Bearer "+apiKey)
conn, _, _ := dialer.Dial("wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes", reqHeader)
defer conn.Close()
conn.WriteJSON(map[string]interface{}{"action": "subscribe"})
for {
var msg map[string]interface{}
conn.ReadJSON(&msg)
if msg["type"] == "new_strikes" {
for _, s := range msg["data"].([]interface{}) {
strike := s.(map[string]interface{})
fmt.Printf("%v lat=%v lon=%v\n", strike["obser_datetime"], strike["lat"], strike["lon"])
}
} else if msg["type"] == "ping" {
conn.WriteJSON(map[string]interface{}{"action": "pong"})
}
}
String API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
HttpClient client = HttpClient.newHttpClient();
WebSocket ws = client.newWebSocketBuilder()
.header("Authorization", "Bearer " + API_KEY)
.buildAsync(URI.create("wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes"),
new WebSocket.Listener() {
public void onOpen(WebSocket webSocket) {
webSocket.sendText("{\"action\":\"subscribe\"}", true);
WebSocket.Listener.super.onOpen(webSocket);
}
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
return WebSocket.Listener.super.onText(webSocket, data, last);
}
}).join();
var apiKey = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
using var ws = new ClientWebSocket();
ws.Options.SetRequestHeader("Authorization", $"Bearer {apiKey}");
await ws.ConnectAsync(
new Uri("wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes"),
CancellationToken.None);
await ws.SendAsync(Encoding.UTF8.GetBytes("{\"action\":\"subscribe\"}"),
WebSocketMessageType.Text, true, CancellationToken.None);
var buffer = new byte[8192];
while (ws.State == WebSocketState.Open)
{
var result = await ws.ReceiveAsync(buffer, CancellationToken.None);
var text = Encoding.UTF8.GetString(buffer, 0, result.Count);
Console.WriteLine(text);
}
$API_KEY = "sk-d5d0542bef7e42e2b8909cb7f42af5fb"; // 更换为您的以 sk- 开头的 API Key 字符串
// 方式一:API Key 直传(通过 WS 握手 Header,使用 textalk/websocket)
// composer require textalk/websocket
$client = new WebSocket\Client("wss://special.data-api.skyviewor.host/fast-lightning/ws/strikes", [
"headers" => ["Authorization" => "Bearer {$API_KEY}"],
]);
$client->text(json_encode(["action" => "subscribe"]));
while (true) {
$msg = json_decode($client->receive(), true);
if ($msg["type"] === "new_strikes") {
foreach ($msg["data"] as $s) {
echo "{$s["obser_datetime"]} lat={$s["lat"]} lon={$s["lon"]}\n";
}
} elseif ($msg["type"] === "ping") {
$client->text(json_encode(["action" => "pong"]));
}
}
连接限制
| 项目 | 限制 |
|---|---|
| 单连接最长时长 | 24 小时 |
| 每个应用同时连接数 | 3 |
关闭码
| Code | 含义 |
|---|---|
4001 |
认证失败 |
4008 |
连接达到 24 小时上限(关闭前约 5 分钟会先推送 server_notice) |
4009 |
连接数超限(服务端立即关闭新连接) |
客户端应根据关闭码决定是等待连接释放后重试,还是重新建连。
配额与限流
| 项目 | 限制 |
|---|---|
| HTTP QPS(每个应用) | 2 |
| WebSocket 同时连接数(每个应用) | 3 |
| 数据令牌有效期 | 5 分钟 |
超过 HTTP QPS 时返回 HTTP 429,响应体形如 {"detail": "请求频率超限 (QPS=2)"}。客户端宜做退避重试。
HTTP 与 WebSocket 分别独立限流:REST 请求不占用 WebSocket 连接数,WebSocket 连接也不计入 HTTP QPS。
与机场快报及其他专线产品共享同一应用下的配额上限,详见 专线接口定价。