API指南
開發者集成與 WebSocket 指南
提供開發者如何整合 API、處理速率限制以及透過 WebSocket 進行即時控制台連線與狀態監控。
開發者集成與 WebSocket 指南
本指南專為希望基於鑽石託管 API 進行二次開發的程式設計師與系統整合人員設計。我們將在此介紹基本的 API 調用流程、程式範例以及最核心的控制台 WebSocket 即時雙向連線機制。
快速起步
發送第一個 API 請求
使用您最熟悉的程式語言或 cURL 測試連線。
curl -X GET "https://panel.diamondhost.tw/api/client" \
-H "Authorization: Bearer dhp_your_secret_api_key" \
-H "Accept: application/json"const axios = require('axios');
axios.get('https://panel.diamondhost.tw/api/client', {
headers: {
'Authorization': 'Bearer dhp_your_secret_api_key',
'Accept': 'application/json'
}
})
.then(res => console.log(res.data))
.catch(err => console.error(err));import requests
headers = {
"Authorization": "Bearer dhp_your_secret_api_key",
"Accept": "application/json"
}
response = requests.get("https://panel.diamondhost.tw/api/client", headers=headers)
print(response.json())package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://panel.diamondhost.tw/api/client", nil)
req.Header.Set("Authorization", "Bearer dhp_your_secret_api_key")
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://panel.diamondhost.tw/api/client"))
.header("Authorization", "Bearer dhp_your_secret_api_key")
.header("Accept", "application/json")
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program {
static async Task Main() {
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "dhp_your_secret_api_key");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.GetAsync("https://panel.diamondhost.tw/api/client");
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
}WebSocket 控制台雙向連線
為了即時監控伺服器(例如:取得遊戲輸出、TPS 指標、記憶體使用率等)或發送命令,您不能一直輪詢 (Polling) API。您必須建立一個長連接的 WebSocket 來與 Node 上的 Wings 守護行程通訊。
WebSocket 的連接密鑰是一次性且有時效限制的。如果連線中斷或連線失敗,您必須重新打 API 索取新的 Token。
建立連線流程
向面板索取 WebSocket 認證資料
發送 GET 請求至 /api/client/servers/{server}/websocket 以獲取一次性的 Token 和 Wings 連線位址。
- 請求端點:
/api/client/servers/{server}/websocket - 回傳範例:
{ "data": { "token": "eyJhbGciOi...", "socket": "wss://node1.diamondhost.tw:8080/api/servers/e1b2c3d4/ws" } }
連接 WebSocket
使用回傳的 socket 網址建立連線。此時連線已開啟,但需要立即進行身份認證。
發送驗證事件 (Authentication)
連線成功後,必須發送第一個 JSON 訊息進行認證。格式如下:
{
"event": "auth",
"args": ["eyJhbGciOi..."] // 剛剛取得的 Token
}Wings 驗證成功後將會回傳驗證成功的通知,並開始向您推播事件。
WebSocket 可訂閱事件 (Inbound Events)
連線建立且認證成功後,您會收到來自 Wings 的各類即時事件通知:
| 事件名稱 (Event) | 回傳參數 (Args) 範例 | 說明 |
|---|---|---|
auth success | 無 | 連線驗證成功 |
status | ["running"] 或 ["offline"] | 伺服器電源狀態變更 |
console output | ["[12:00:00 INFO]: Player joined the game"] | 伺服器控制台的標準輸出 (Console Log) |
stats | {"cpu_absolute": 12.5, "memory_bytes": 1073741824, ...} | 伺服器的 CPU、記憶體、硬碟及頻寬的即時資源數據 |
token expiring | 無 | 當前的認證 Token 即將過期(通常在使用數小時後),提示需重新獲取 Token |
WebSocket 發送指令事件 (Outbound Events)
您可以透過此 WebSocket 即時發送指令至控制台,或操作伺服器開關:
1. 發送控制台命令
發送事件名稱為 send command,並附帶要執行的指令:
{
"event": "send command",
"args": ["say Hello from my bot!"]
}2. 切換伺服器電源狀態
發送事件名稱為 send state,可用參數包括 start, stop, restart, kill:
{
"event": "send state",
"args": ["restart"]
}完整的 Node.js 連線範例
以下是使用 ws 庫連接鑽石託管伺服器 WebSocket 的完整實作範例。
const WebSocket = require('ws');
const axios = require('axios');
const PANEL_URL = 'https://panel.diamondhost.tw';
const API_KEY = 'dhp_your_secret_api_key';
const UUID = 'e1b2c3d4';
async function connectToConsole() {
try {
const response = await axios.get(`${PANEL_URL}/api/client/servers/${UUID}/websocket`, {
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Accept': 'application/json'
}
});
const { token, socket } = response.data.data;
const ws = new WebSocket(socket, {
headers: {
'Origin': PANEL_URL
}
});
ws.on('open', () => {
console.log('Successfully connected to Wings WebSocket!');
ws.send(JSON.stringify({
event: 'auth',
args: [token]
}));
});
ws.on('message', (data) => {
const payload = JSON.parse(data.toString());
switch (payload.event) {
case 'auth success':
console.log('Authentication successful. Ready to receive events.');
break;
case 'status':
console.log(`Server status changed to: ${payload.args[0]}`);
break;
case 'console output':
console.log(`[Console] ${payload.args[0]}`);
break;
case 'stats':
const stats = JSON.parse(payload.args[0]);
console.log(`[Stats] CPU: ${stats.cpu_absolute}%, RAM: ${(stats.memory_bytes / 1024 / 1024).toFixed(2)} MB`);
break;
case 'token expiring':
console.log('Token is expiring. Re-fetching new token...');
break;
}
});
ws.on('close', () => {
console.log('WebSocket connection closed.');
});
ws.on('error', (err) => {
console.error('WebSocket Error:', err);
});
} catch (error) {
console.error('Failed to connect:', error.message);
}
}
connectToConsole();