> For the complete documentation index, see [llms.txt](https://docs.infoway.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.infoway.io/websocket-api/subscribe-and-unsubscribe/real-time-news.md).

# 实时新闻（News）订阅

### API说明

该 Websocket 用于获取新闻的实时推送。

连接成功后，客户端按 **语言（lang）** 订阅：

* `data.lang` 必填，单一语言（不区分大小写，服务端会归一化为小写），取值见下方语言枚举
* 同一连接再次订阅会**覆盖**上一次的 `lang`
* 套餐需开通新闻权限（`newsFlag=1`），否则握手失败
* 每个 `apikey` **仅允许一个**连接；已有连接时新连接会被拒绝

### 语言枚举

订阅时 `lang` 仅支持以下取值。右侧为国家/市场代码（`en` 对应全球，国家代码为空）：

| lang      | 国家/市场代码 | 说明   |
| --------- | ------- | ---- |
| `en`      | （空）     | 英语   |
| `zh-Hans` | `CN`    | 简体中文 |
| `zh-Hant` | `HK`    | 繁体中文 |
| `ja`      | `JP`    | 日语   |
| `ko`      | `KR`    | 韩语   |
| `de`      | `DE`    | 德语   |
| `fr`      | `FR`    | 法语   |
| `es`      | `ES`    | 西班牙语 |
| `pt`      | `BR`    | 葡萄牙语 |
| `ru`      | `RU`    | 俄语   |
| `tr`      | `TR`    | 土耳其语 |

### 请求频率

请保持心跳，建议每 **30 秒**发送一次心跳（协议号 `10010`）。若服务端超过 **60 秒**未收到心跳（业务心跳或 WebSocket Ping），将自动断连。

### 错误码说明

参考Websocket错误码说明

常见握手/连接相关错误：

| code  | 说明                             |
| ----- | ------------------------------ |
| `200` | 握手成功                           |
| `507` | 参数缺失（如缺少 `data` / `data.lang`） |
| `513` | 心跳超时                           |
| `514` | WebSocket 路径错误                 |
| `515` | 请求不是 JSON                      |
| `517` | 握手失败：缺少 apikey                 |
| `518` | 握手失败：apikey 不存在                |
| `519` | 握手失败：无新闻权限（newsFlag!=1）        |
| `520` | 握手失败：该 apikey 已有连接             |
| `521` | 握手失败：服务器连接数已满                  |

### 接口地址

```
wss://data.infoway.io/news?apikey=YourAPIKey
```

> 路径必须为 `/news`，并通过 query 传入 `apikey`。

### 请求数量

同一 Websocket 连接同时仅保留 **一份**订阅（再次订阅覆盖旧订阅）。每个 `apikey` 同时仅允许 **一个**连接。

### 请求（协议号：10020）

```json
{
    "code": 10020,
    "trace": "423afec425004bd8a5e02e1ba5f9b2b0",
    "data": {
        "lang": "en"
    }
}
```

| 参数名     | 类型      | 必填 | 描述                        | 示例值                                |
| ------- | ------- | -- | ------------------------- | ---------------------------------- |
| `code`  | Integer | 是  | 请求的协议号                    | 实时新闻订阅协议号：`10020`                  |
| `trace` | String  | 是  | 可追溯ID（随机字符串）              | `423afec425004bd8a5e02e1ba5f9b2b0` |
| `data`  | JSON    | 是  | 订阅数据                      |                                    |
| `＜lang` | String  | 是  | 订阅语言（单一语言，不区分大小写），见上方语言枚举 | `en`                               |

### 应答（协议号：10021）

```json
{
    "code": 10021,
    "trace": "423afec425004bd8a5e02e1ba5f9b2b0",
    "msg": "ok",
    "data": {
        "lang": "en"
    }
}
```

| 字段名     | 类型      | 必填 | 描述              | 示例值                                |
| ------- | ------- | -- | --------------- | ---------------------------------- |
| `code`  | Integer | 是  | 响应协议号           | 订阅实时新闻响应协议号：`10021`                |
| `trace` | String  | 是  | 订阅传入参数可追溯 id    | `423afec425004bd8a5e02e1ba5f9b2b0` |
| `msg`   | String  | 是  | 响应              | `ok`                               |
| `data`  | JSON    | 是  | 当前生效的订阅条件       |                                    |
| `＜lang` | String  | 是  | 已订阅语言（归一化后的小写值） | `en`                               |

### 推送（协议号：10022）

```json
{
    "code": 10022,
    "data": {
        "dk": "a1b2c3d4e5f6...",
        "country": "US",
        "lang": "en",
        "route": "lang",
        "title": "Apple raises full-year revenue forecast",
        "published": 1747552358,
        "urgency": 2,
        "provider": "reuters",
        "symbols": ["AAPL"],
        "link": "https://www.example.com/article/123",
        "content": "Apple Inc said on Monday it expects...",
        "sd": "Apple raises full-year outlook on strong iPhone demand"
    }
}
```

| 字段名          | 类型      | 必填 | 描述                        | 示例值                                       |
| ------------ | ------- | -- | ------------------------- | ----------------------------------------- |
| `code`       | Integer | 是  | 推送协议号                     | 实时新闻推送协议号：`10022`                         |
| `data`       | JSON    | 是  | 推送数据实体                    |                                           |
| `＜dk`        | String  | 是  | 去重键（md5(title + content)） | `a1b2c3d4e5f6...`                         |
| `＜country`   | String  | 否  | 国家（全球流可能为空）               | `US`                                      |
| `＜lang`      | String  | 是  | 语言                        | `en` / `zh-Hans`                          |
| `＜route`     | String  | 是  | 采集路线                      | `country` / `lang`                        |
| `＜title`     | String  | 是  | 标题                        | `Apple raises full-year revenue forecast` |
| `＜published` | Long    | 是  | 发布时间戳（Unix 秒级）            | `1747552358`                              |
| `＜urgency`   | Integer | 是  | 紧急程度，越小越紧急                | `2`                                       |
| `＜provider`  | String  | 是  | 新闻源                       | `reuters` / `gelonghui`                   |
| `＜symbols`   | Array   | 否  | 关联标的列表                    | `["AAPL"]`                                |
| `＜link`      | String  | 否  | 外部链接（快讯类新闻）               | `https://www.example.com/article/123`     |
| `＜content`   | String  | 否  | 正文纯文本                     |                                           |
| `＜sd`        | String  | 否  | 摘要（shortDescription）      |                                           |

### 心跳（协议号：10010）

```json
{
    "code": 10010,
    "trace": "423afec425004bd8a5e02e1ba5f9b2b0"
}
```

服务端收到后刷新活跃时间，**不回业务应答**。也可使用 WebSocket 标准 `Ping` / `Pong` 保活。
