跳转至

闪电快报

闪电快报为专线接口产品,提供全球闪电定位数据的低延迟 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 在网络传输中的泄露风险。流程如下:

  1. 用 API Key 换取临时数据令牌(有效期 5 分钟)
  2. 用令牌调用数据接口或建立 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 200count0data 为空数组 []

有数据时的响应示例

{
  "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 / +10 多为未知
mds int ns 最大时间偏差;越小通常定位越好
mcg int ° 探测站覆盖角度间隙;实测多为整数,越小通常几何越好
status int 状态 / 质量标记
region int 网络区域编号
arrived_at string 本服务入库时间(UTC,ISO 8601)

字段说明

lat / lon 为 WGS84 经纬度。业务一般以坐标与时间字段为主,mds / mcg 可作质量参考。响应中可能含 delaylonclatc 等扩展字段,以本表为准;不返回 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"}

推送消息格式

服务端每秒批量推送,typenew_strikesdata数组(可能包含 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。

与机场快报及其他专线产品共享同一应用下的配额上限,详见 专线接口定价