> ## Documentation Index
> Fetch the complete documentation index at: https://hoalulab.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Luồng điều khiển kết nối

> Client thực hiện flow điều khiển theo thứ tự:
1. Server gửi `welcome` sau khi kết nối.
2. Client gửi `auth` và chờ `auth_success`.
3. Client gửi `subscribe` hoặc `unsubscribe` để quản lý các channel dữ liệu.
4. Server có thể gửi `ping`; client phản hồi bằng `pong`.
5. Client xử lý các phản hồi `subscribed`, `unsubscribed`, `error` và `connection_expired`.



## AsyncAPI

````yaml vi/openapi/dnse-v2-asyncapi.yaml controlStream
id: controlStream
title: Luồng điều khiển kết nối
description: >-
  Client thực hiện flow điều khiển theo thứ tự:

  1. Server gửi `welcome` sau khi kết nối.

  2. Client gửi `auth` và chờ `auth_success`.

  3. Client gửi `subscribe` hoặc `unsubscribe` để quản lý các channel dữ liệu.

  4. Server có thể gửi `ping`; client phản hồi bằng `pong`.

  5. Client xử lý các phản hồi `subscribed`, `unsubscribed`, `error` và
  `connection_expired`.
servers:
  - id: production
    protocol: wss
    host: ws-openapi.dnse.com.vn
    bindings: []
    variables: []
address: /v1/stream
parameters: []
bindings:
  - protocol: ws
    version: 0.1.0
    value:
      method: GET
      query:
        type: object
        additionalProperties: false
        required:
          - encoding
        properties:
          encoding:
            type: string
            const: json
            default: json
            description: Định dạng mã hóa dữ liệu WebSocket.
    schemaProperties:
      - name: method
        type: string
        description: GET
        required: false
      - name: query
        type: object
        required: false
        properties:
          - name: encoding
            type: string
            description: Định dạng mã hóa dữ liệu WebSocket.
            required: true
operations:
  - &ref_1
    id: onAuthRequest
    title: Gửi yêu cầu xác thực
    description: Client gửi API key, chữ ký và nonce để xác thực kết nối.
    type: receive
    messages:
      - &ref_12
        id: authRequest
        contentType: application/json
        payload:
          - name: Yêu cầu xác thực WebSocket
            description: Xác thực kết nối bằng API key và chữ ký HMAC-SHA256.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message xác thực.
                required: true
              - name: api_key
                type: string
                description: API key do DNSE cấp.
                required: true
              - name: signature
                type: string
                description: >-
                  Chữ ký HMAC-SHA256 dạng hexadecimal của
                  `api_key:timestamp:nonce`.
                required: true
              - name: timestamp
                type: integer
                description: Unix timestamp tính bằng giây dùng để tạo chữ ký.
                required: true
              - name: nonce
                type: string
                description: >-
                  Giá trị duy nhất cho yêu cầu xác thực, được truyền dưới dạng
                  chuỗi.
                required: true
        headers: []
        jsonPayloadSchema:
          type: object
          additionalProperties: false
          required:
            - action
            - api_key
            - signature
            - timestamp
            - nonce
          properties:
            action:
              type: string
              description: Loại message xác thực.
              const: auth
              x-parser-schema-id: <anonymous-schema-7>
            api_key:
              type: string
              description: API key do DNSE cấp.
              x-parser-schema-id: <anonymous-schema-8>
            signature:
              type: string
              description: >-
                Chữ ký HMAC-SHA256 dạng hexadecimal của
                `api_key:timestamp:nonce`.
              pattern: ^[0-9a-fA-F]{64}$
              x-parser-schema-id: <anonymous-schema-9>
            timestamp:
              type: integer
              format: int64
              description: Unix timestamp tính bằng giây dùng để tạo chữ ký.
              x-parser-schema-id: <anonymous-schema-10>
            nonce:
              type: string
              description: >-
                Giá trị duy nhất cho yêu cầu xác thực, được truyền dưới dạng
                chuỗi.
              x-parser-schema-id: <anonymous-schema-11>
          x-parser-schema-id: <anonymous-schema-6>
        title: Yêu cầu xác thực WebSocket
        description: Xác thực kết nối bằng API key và chữ ký HMAC-SHA256.
        example: |-
          {
            "action": "auth",
            "api_key": "your_api_key",
            "signature": "a3f9c2d1e8b74c8d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d",
            "timestamp": 1750000000,
            "nonce": "1750000000123456"
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: authRequest
    bindings: []
    extensions: &ref_0
      - id: x-parser-unique-object-id
        value: controlStream
  - &ref_5
    id: onWelcomeMessage
    title: Nhận welcome message
    description: Server gửi welcome message sau khi kết nối WebSocket thành công.
    type: send
    messages:
      - &ref_16
        id: welcomeMessage
        contentType: application/json
        payload:
          - name: Welcome message
            description: Message server gửi sau khi kết nối WebSocket thành công.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message điều khiển.
                required: true
              - name: session_id
                type: string
                description: Mã phiên kết nối WebSocket.
                required: true
              - name: timestamp
                type: integer
                description: Unix timestamp tính bằng giây tại thời điểm gửi message.
                required: true
              - name: message
                type: string
                description: Nội dung hướng dẫn xác thực.
                required: true
        headers: []
        jsonPayloadSchema:
          type: object
          description: Welcome message server gửi sau khi kết nối WebSocket thành công.
          additionalProperties: false
          required:
            - action
            - session_id
            - timestamp
            - message
          properties:
            action:
              type: string
              description: Loại message điều khiển.
              const: welcome
              x-parser-schema-id: <anonymous-schema-2>
            session_id:
              type: string
              description: Mã phiên kết nối WebSocket.
              x-parser-schema-id: <anonymous-schema-3>
            timestamp:
              type: integer
              format: int64
              description: Unix timestamp tính bằng giây tại thời điểm gửi message.
              x-parser-schema-id: <anonymous-schema-4>
            message:
              type: string
              description: Nội dung hướng dẫn xác thực.
              x-parser-schema-id: <anonymous-schema-5>
          x-parser-schema-id: <anonymous-schema-1>
        title: Welcome message
        description: Message server gửi sau khi kết nối WebSocket thành công.
        example: |-
          {
            "action": "welcome",
            "session_id": "conn_1782199800969809263",
            "timestamp": 1750000000,
            "message": "Please authenticate within 30 seconds"
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: welcomeMessage
    bindings: []
    extensions: *ref_0
  - &ref_6
    id: onAuthSuccessMessage
    title: Nhận kết quả xác thực
    description: Server thông báo xác thực thành công và các giới hạn kết nối.
    type: send
    messages:
      - &ref_17
        id: authSuccessMessage
        contentType: application/json
        payload:
          - name: Xác thực thành công
            description: Message server gửi sau khi xác thực kết nối thành công.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message xác thực.
                required: true
              - name: user_id
                type: string
                description: Mã người dùng hoặc API key đã xác thực.
                required: true
              - name: capabilities
                type: object
                required: true
                properties:
                  - name: batch_delivery
                    type: boolean
                    description: Cho biết kết nối có hỗ trợ gửi message theo lô hay không.
                    required: true
              - name: rate_limit
                type: object
                required: true
                properties:
                  - name: messages_per_second
                    type: integer
                    description: Số message tối đa mỗi giây.
                    required: true
                  - name: subscriptions_max
                    type: integer
                    description: Số lượng subscription tối đa.
                    required: true
        headers: []
        jsonPayloadSchema:
          type: object
          description: Kết quả xác thực kết nối WebSocket thành công.
          additionalProperties: false
          required:
            - action
            - user_id
            - capabilities
            - rate_limit
          properties:
            action:
              type: string
              description: Loại message xác thực.
              const: auth_success
              x-parser-schema-id: <anonymous-schema-13>
            user_id:
              type: string
              description: Mã người dùng hoặc API key đã xác thực.
              x-parser-schema-id: <anonymous-schema-14>
            capabilities:
              type: object
              additionalProperties: false
              required:
                - batch_delivery
              properties:
                batch_delivery:
                  type: boolean
                  description: Cho biết kết nối có hỗ trợ gửi message theo lô hay không.
                  x-parser-schema-id: <anonymous-schema-16>
              x-parser-schema-id: <anonymous-schema-15>
            rate_limit:
              type: object
              additionalProperties: false
              required:
                - messages_per_second
                - subscriptions_max
              properties:
                messages_per_second:
                  type: integer
                  description: Số message tối đa mỗi giây.
                  x-parser-schema-id: <anonymous-schema-18>
                subscriptions_max:
                  type: integer
                  description: Số lượng subscription tối đa.
                  x-parser-schema-id: <anonymous-schema-19>
              x-parser-schema-id: <anonymous-schema-17>
          x-parser-schema-id: <anonymous-schema-12>
        title: Xác thực thành công
        description: Message server gửi sau khi xác thực kết nối thành công.
        example: |-
          {
            "action": "auth_success",
            "user_id": "your_api_key",
            "capabilities": {
              "batch_delivery": false
            },
            "rate_limit": {
              "messages_per_second": 100,
              "subscriptions_max": 100
            }
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: authSuccessMessage
    bindings: []
    extensions: *ref_0
  - &ref_7
    id: onPingMessage
    title: Nhận ping
    description: Server gửi ping để kiểm tra kết nối WebSocket.
    type: send
    messages:
      - &ref_18
        id: pingMessage
        contentType: application/json
        payload:
          - name: Ping heartbeat
            description: Message server gửi để kiểm tra kết nối WebSocket.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message heartbeat.
                required: true
              - name: timestamp
                type: integer
                description: Unix timestamp tính bằng mili giây tại thời điểm gửi ping.
                required: true
        headers: []
        jsonPayloadSchema:
          type: object
          description: Ping server gửi để kiểm tra kết nối WebSocket.
          additionalProperties: false
          required:
            - action
            - timestamp
          properties:
            action:
              type: string
              description: Loại message heartbeat.
              const: ping
              x-parser-schema-id: <anonymous-schema-21>
            timestamp:
              type: integer
              format: int64
              description: Unix timestamp tính bằng mili giây tại thời điểm gửi ping.
              x-parser-schema-id: <anonymous-schema-22>
          x-parser-schema-id: <anonymous-schema-20>
        title: Ping heartbeat
        description: Message server gửi để kiểm tra kết nối WebSocket.
        example: |-
          {
            "action": "ping",
            "timestamp": 1750000000123
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: pingMessage
    bindings: []
    extensions: *ref_0
  - &ref_2
    id: onPongRequest
    title: Gửi pong
    description: Client phản hồi pong để duy trì kết nối WebSocket.
    type: receive
    messages:
      - &ref_13
        id: pongRequest
        contentType: application/json
        payload:
          - name: Phản hồi heartbeat
            description: Client gửi pong để duy trì kết nối WebSocket.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message phản hồi heartbeat.
                required: true
              - name: timestamp
                type: integer
                description: Timestamp ping được client echo lại để đo độ trễ.
                required: false
        headers: []
        jsonPayloadSchema:
          type: object
          additionalProperties: false
          required:
            - action
          properties:
            action:
              type: string
              description: Loại message phản hồi heartbeat.
              const: pong
              x-parser-schema-id: <anonymous-schema-24>
            timestamp:
              type: integer
              format: int64
              description: Timestamp ping được client echo lại để đo độ trễ.
              x-parser-schema-id: <anonymous-schema-25>
          x-parser-schema-id: <anonymous-schema-23>
        title: Phản hồi heartbeat
        description: Client gửi pong để duy trì kết nối WebSocket.
        example: |-
          {
            "action": "pong"
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: pongRequest
    bindings: []
    extensions: *ref_0
  - &ref_3
    id: onUnsubscribeRequest
    title: Gửi yêu cầu hủy đăng ký
    description: Client hủy đăng ký một hoặc nhiều channel dữ liệu.
    type: receive
    messages:
      - &ref_14
        id: unsubscribeRequest
        contentType: application/json
        payload:
          - name: Yêu cầu hủy đăng ký
            description: Client yêu cầu hủy đăng ký một hoặc nhiều channel dữ liệu.
            type: object
            properties:
              - name: action
                type: string
                description: Loại yêu cầu đăng ký.
                required: true
              - name: channels
                type: array
                description: Danh sách channel cần hủy đăng ký.
                required: true
                properties:
                  - name: name
                    type: string
                    description: Tên channel cần hủy đăng ký.
                    required: true
                  - name: symbols
                    type: array
                    description: >-
                      Danh sách mã cần hủy; truyền mảng rỗng nếu channel không
                      lọc theo mã.
                    required: true
                    properties:
                      - name: item
                        type: string
                        required: false
        headers: []
        jsonPayloadSchema:
          type: object
          description: Yêu cầu hủy đăng ký các channel dữ liệu.
          additionalProperties: false
          required:
            - action
            - channels
          properties:
            action:
              type: string
              description: Loại yêu cầu đăng ký.
              const: unsubscribe
              x-parser-schema-id: <anonymous-schema-36>
            channels:
              type: array
              minItems: 1
              uniqueItems: true
              description: Danh sách channel cần hủy đăng ký.
              items:
                type: object
                additionalProperties: false
                required:
                  - name
                  - symbols
                properties:
                  name:
                    type: string
                    description: Tên channel cần hủy đăng ký.
                    x-parser-schema-id: <anonymous-schema-39>
                  symbols:
                    type: array
                    description: >-
                      Danh sách mã cần hủy; truyền mảng rỗng nếu channel không
                      lọc theo mã.
                    items:
                      type: string
                      x-parser-schema-id: <anonymous-schema-41>
                    x-parser-schema-id: <anonymous-schema-40>
                x-parser-schema-id: <anonymous-schema-38>
              x-parser-schema-id: <anonymous-schema-37>
          x-parser-schema-id: <anonymous-schema-35>
        title: Yêu cầu hủy đăng ký
        description: Client yêu cầu hủy đăng ký một hoặc nhiều channel dữ liệu.
        example: |-
          {
            "action": "unsubscribe",
            "channels": [
              {
                "name": "tick.G1.json",
                "symbols": [
                  "ACB"
                ]
              }
            ]
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: unsubscribeRequest
    bindings: []
    extensions: *ref_0
  - &ref_4
    id: onSubscribeRequest
    title: Gửi yêu cầu đăng ký
    description: Client đăng ký một hoặc nhiều channel dữ liệu.
    type: receive
    messages:
      - &ref_15
        id: subscribeRequest
        contentType: application/json
        payload:
          - name: Yêu cầu đăng ký
            description: Client yêu cầu đăng ký một hoặc nhiều channel dữ liệu.
            type: object
            properties:
              - name: action
                type: string
                description: Loại yêu cầu đăng ký.
                required: true
              - name: channels
                type: array
                description: Danh sách channel cần đăng ký.
                required: true
                properties:
                  - name: name
                    type: string
                    description: Tên channel cần đăng ký.
                    required: true
                  - name: symbols
                    type: array
                    description: >-
                      Danh sách mã cần đăng ký; truyền mảng rỗng nếu channel
                      không lọc theo mã.
                    required: true
                    properties:
                      - name: item
                        type: string
                        required: false
        headers: []
        jsonPayloadSchema:
          type: object
          description: Yêu cầu đăng ký các channel dữ liệu.
          additionalProperties: false
          required:
            - action
            - channels
          properties:
            action:
              type: string
              description: Loại yêu cầu đăng ký.
              const: subscribe
              x-parser-schema-id: <anonymous-schema-27>
            channels:
              type: array
              minItems: 1
              uniqueItems: true
              description: Danh sách channel cần đăng ký.
              items:
                type: object
                additionalProperties: false
                required:
                  - name
                  - symbols
                properties:
                  name:
                    type: string
                    description: Tên channel cần đăng ký.
                    x-parser-schema-id: <anonymous-schema-30>
                  symbols:
                    type: array
                    description: >-
                      Danh sách mã cần đăng ký; truyền mảng rỗng nếu channel
                      không lọc theo mã.
                    items:
                      type: string
                      x-parser-schema-id: <anonymous-schema-32>
                    x-parser-schema-id: <anonymous-schema-31>
                x-parser-schema-id: <anonymous-schema-29>
              x-parser-schema-id: <anonymous-schema-28>
          x-parser-schema-id: <anonymous-schema-26>
        title: Yêu cầu đăng ký
        description: Client yêu cầu đăng ký một hoặc nhiều channel dữ liệu.
        example: |-
          {
            "action": "subscribe",
            "channels": [
              {
                "name": "tick.G1.json",
                "symbols": [
                  "ACB",
                  "HPG"
                ]
              }
            ]
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: subscribeRequest
    bindings: []
    extensions: *ref_0
  - &ref_8
    id: onSubscribedMessage
    title: Nhận xác nhận đăng ký
    description: Server xác nhận đăng ký channel thành công.
    type: send
    messages:
      - &ref_19
        id: subscribedMessage
        contentType: application/json
        payload:
          - name: Đăng ký thành công
            description: Server xác nhận client đã đăng ký channel dữ liệu.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message xác nhận đăng ký.
                required: true
        headers: []
        jsonPayloadSchema:
          type: object
          description: Xác nhận server đã đăng ký channel dữ liệu.
          additionalProperties: false
          required:
            - action
          properties:
            action:
              type: string
              description: Loại message xác nhận đăng ký.
              const: subscribed
              x-parser-schema-id: <anonymous-schema-34>
          x-parser-schema-id: <anonymous-schema-33>
        title: Đăng ký thành công
        description: Server xác nhận client đã đăng ký channel dữ liệu.
        example: |-
          {
            "action": "subscribed"
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: subscribedMessage
    bindings: []
    extensions: *ref_0
  - &ref_9
    id: onUnsubscribedMessage
    title: Nhận xác nhận hủy đăng ký
    description: Server xác nhận hủy đăng ký channel thành công.
    type: send
    messages:
      - &ref_20
        id: unsubscribedMessage
        contentType: application/json
        payload:
          - name: Hủy đăng ký thành công
            description: Server xác nhận client đã hủy đăng ký channel dữ liệu.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message xác nhận hủy đăng ký.
                required: true
        headers: []
        jsonPayloadSchema:
          type: object
          description: Xác nhận server đã hủy đăng ký channel dữ liệu.
          additionalProperties: false
          required:
            - action
          properties:
            action:
              type: string
              description: Loại message xác nhận hủy đăng ký.
              const: unsubscribed
              x-parser-schema-id: <anonymous-schema-43>
          x-parser-schema-id: <anonymous-schema-42>
        title: Hủy đăng ký thành công
        description: Server xác nhận client đã hủy đăng ký channel dữ liệu.
        example: |-
          {
            "action": "unsubscribed"
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: unsubscribedMessage
    bindings: []
    extensions: *ref_0
  - &ref_10
    id: onErrorMessage
    title: Nhận lỗi điều khiển
    description: Server gửi lỗi điều khiển kèm mã và nội dung lỗi.
    type: send
    messages:
      - &ref_21
        id: errorMessage
        contentType: application/json
        payload:
          - name: Lỗi điều khiển
            description: Server gửi lỗi điều khiển trong quá trình kết nối hoặc đăng ký.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message lỗi điều khiển.
                required: true
              - name: code
                type: string
                description: Mã lỗi.
                required: true
              - name: message
                type: string
                description: Nội dung lỗi.
                required: true
        headers: []
        jsonPayloadSchema:
          type: object
          description: Lỗi server gửi trong quá trình kết nối hoặc đăng ký.
          additionalProperties: false
          required:
            - action
            - code
            - message
          properties:
            action:
              type: string
              description: Loại message lỗi điều khiển.
              const: error
              x-parser-schema-id: <anonymous-schema-45>
            code:
              type: string
              description: Mã lỗi.
              x-parser-schema-id: <anonymous-schema-46>
            message:
              type: string
              description: Nội dung lỗi.
              x-parser-schema-id: <anonymous-schema-47>
          x-parser-schema-id: <anonymous-schema-44>
        title: Lỗi điều khiển
        description: Server gửi lỗi điều khiển trong quá trình kết nối hoặc đăng ký.
        example: |-
          {
            "action": "error",
            "code": "AUTH_FAILED",
            "message": "authentication failed: invalid signature"
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: errorMessage
    bindings: []
    extensions: *ref_0
  - &ref_11
    id: onConnectionExpiredMessage
    title: Nhận thông báo hết hạn kết nối
    description: Server thông báo kết nối đạt giới hạn thời gian và yêu cầu reconnect.
    type: send
    messages:
      - &ref_22
        id: connectionExpiredMessage
        contentType: application/json
        payload:
          - name: Kết nối hết hạn
            description: >-
              Server thông báo kết nối đạt giới hạn thời gian và yêu cầu
              reconnect.
            type: object
            properties:
              - name: action
                type: string
                description: Loại message thông báo hết hạn kết nối.
                required: true
              - name: code
                type: string
                description: Mã lý do kết nối hết hạn.
                required: true
              - name: message
                type: string
                description: Nội dung hướng dẫn client kết nối lại.
                required: true
        headers: []
        jsonPayloadSchema:
          type: object
          description: Thông báo kết nối đã đạt giới hạn thời gian.
          additionalProperties: false
          required:
            - action
            - code
            - message
          properties:
            action:
              type: string
              description: Loại message thông báo hết hạn kết nối.
              const: connection_expired
              x-parser-schema-id: <anonymous-schema-49>
            code:
              type: string
              description: Mã lý do kết nối hết hạn.
              const: MAX_DURATION_EXCEEDED
              x-parser-schema-id: <anonymous-schema-50>
            message:
              type: string
              description: Nội dung hướng dẫn client kết nối lại.
              x-parser-schema-id: <anonymous-schema-51>
          x-parser-schema-id: <anonymous-schema-48>
        title: Kết nối hết hạn
        description: Server thông báo kết nối đạt giới hạn thời gian và yêu cầu reconnect.
        example: |-
          {
            "action": "connection_expired",
            "code": "MAX_DURATION_EXCEEDED",
            "message": "Connection expired after 8 hours. Please reconnect."
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: connectionExpiredMessage
    bindings: []
    extensions: *ref_0
sendOperations:
  - *ref_1
  - *ref_2
  - *ref_3
  - *ref_4
receiveOperations:
  - *ref_5
  - *ref_6
  - *ref_7
  - *ref_8
  - *ref_9
  - *ref_10
  - *ref_11
sendMessages:
  - *ref_12
  - *ref_13
  - *ref_14
  - *ref_15
receiveMessages:
  - *ref_16
  - *ref_17
  - *ref_18
  - *ref_19
  - *ref_20
  - *ref_21
  - *ref_22
extensions:
  - id: x-parser-unique-object-id
    value: controlStream
securitySchemes: []

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.