راهنمای WebSocket
APIهای بیدرنگ وبسوکت برای اعلانها، گفتوگو و جریان هوش تهدید. اتصالهای پایدار دوسویه با اتصال دوبارهٔ خودکار.
APIهای بیدرنگ WebSocket
اتصالهای پایدار دوسویه برای اعلانهای زنده، پیامرسانی گفتوگو و جریان هوش تهدید. کمتأخیر، رویدادمحور و آمادهٔ تولید.
نمای کلی
OrbVPN سه نقطهٔ پایانی وبسوکت در دو سرویس فراهم میکند. اتصالهای وبسوکت کانالهایی پایدار و کاملاً دوسویهاند که به سرور امکان میدهند بدون نظرخواهی مکرر، رویدادها را بیدرنگ به کلاینت شما بفرستد.
معماری رویدادمحور
در کانالهای رویداد مشخصی مشترک شوید و پیامهای قالببندیشده با JSON را همان لحظهٔ رخ دادن بگیرید. بدون نظرخواهی مکرر، بدون هدر رفتن پهنای باند.
اتصال دوبارهٔ خودکار
کیتها اتصال دوباره را با عقبنشینی نمایی مدیریت میکنند. پیادهسازیهای دستی باید راهبرد اتصال دوبارهٔ مستندشده در ادامه را دنبال کنند.
ضربان / زندهنگهداشتن
قابهای پینگ-پنگ اتصالها را از میان پروکسیها و توزیعکنندههای بار زنده نگه میدارند. کلاینتها باید ظرف ۳۰ ثانیه به پینگ سرور پاسخ دهند.
جریان اتصال
هر اتصال وبسوکت، فارغ از نقطهٔ پایانی، از همان چرخهٔ زندگی پیروی میکند.
نقاط پایانی
۱. اعلانهای OrbNET
اعلانهای بیدرنگ برای رویدادهای حساب، بهروزرسانی اشتراک، تغییر وضعیت دستگاه و هشدارهای سرور.
wss://api.orbai.world/ws/notificationsاعلانهای بیدرنگ حساب OrbVPN خود را بگیرید. به رمزینهٔ دسترسی معتبر JWT نیاز دارد که بهعنوان رمزینهٔ حامل در دستدهی اولیهٔ اتصال داده میشود.
notificationsubscription_updatedevice_statusserver_alertماندگاری اعلان
اعلانها سمت سرور نگه داشته میشوند. اگر کلاینت شما قطع شود، اعلانهای از دست رفته هنگام اتصال دوباره بهصورت گروهی تحویل میشوند (تا ۱۰۰ رویداد از ۲۴ ساعت گذشته).
۲. گفتوگوی OrbNET
پیامرسانی بیدرنگ برای گفتوگوی پشتیبانی، ارتباط با فروشندگان و پیامرسانی دروناپی.
wss://api.orbai.world/ws/chatپیامرسانی دوسویهٔ گفتوگو برای پشتیبانی OrbVPN و ارتباط دروناپی. به رمزینهٔ دسترسی معتبر JWT نیاز دارد.
messagetypingread_receipt۳. جریان تهدید OrbGuard
خوراک زندهٔ هوش تهدید برای تشخیص بیدرنگ تهدید و پایش امنیتی.
wss://guard.orbai.world/ws/threatsجریان بیدرنگ هوش تهدید از OrbGuard Labs. به کلید API نیاز دارد که از راه سرآیند X-API-Key یا بهعنوان پارامتر پرسوجو داده میشود.
threat_detectedscan_completealertحجم جریان تهدید
جریان تهدید OrbGuard میتواند حجم بالایی از رویداد تولید کند (بیش از ۱۰۰ رویداد در دقیقه هنگام کارزارهای فعال). در مصرفکنندهٔ خود بافر و محدودسازی نرخ پیاده کنید تا برنامهتان زیر بار نرود.
نمونههای اتصال
جاوااسکریپت
// OrbNET Notifications WebSocket
const token = 'eyJhbGciOiJIUzI1NiIs...';
const ws = new WebSocket(
`wss://api.orbai.world/ws/notifications?token=${token}`
);
ws.onopen = () => {
console.log('Connected to OrbNET notifications');
// Subscribe to specific channels
ws.send(JSON.stringify({
type: 'subscribe',
channels: ['notification', 'device_status', 'subscription_update'],
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'connection_ack':
console.log(`Session: ${data.sessionId}`);
break;
case 'notification':
console.log(`[Notification] ${data.payload.title}: ${data.payload.message}`);
break;
case 'device_status':
console.log(`[Device] ${data.payload.deviceId}: ${data.payload.status}`);
break;
case 'subscription_update':
console.log(`[Subscription] ${data.payload.event}: ${data.payload.planName}`);
break;
case 'server_alert':
console.log(`[Alert] ${data.payload.severity}: ${data.payload.message}`);
break;
default:
console.log('Unknown event:', data);
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = (event) => {
console.log(`Connection closed: ${event.code} ${event.reason}`);
// Implement reconnection logic (see below)
};پایتون
import asyncio
import json
import websockets
async def connect_notifications():
token = "eyJhbGciOiJIUzI1NiIs..."
uri = f"wss://api.orbai.world/ws/notifications?token={token}"
async for websocket in websockets.connect(uri):
try:
# Subscribe to channels
await websocket.send(json.dumps({
"type": "subscribe",
"channels": ["notification", "device_status"],
}))
async for raw_message in websocket:
event = json.loads(raw_message)
if event["type"] == "connection_ack":
print(f"Connected. Session: {event['sessionId']}")
elif event["type"] == "notification":
payload = event["payload"]
print(f"[Notification] {payload['title']}: {payload['message']}")
elif event["type"] == "device_status":
payload = event["payload"]
print(f"[Device] {payload['deviceId']}: {payload['status']}")
elif event["type"] == "ping":
await websocket.pong()
except websockets.ConnectionClosed:
print("Connection lost. Reconnecting...")
continue # websockets.connect handles reconnection
asyncio.run(connect_notifications())Go
package main
import (
"encoding/json"
"fmt"
"log"
"net/url"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
type Event struct {
Type string `json:"type"`
SessionID string `json:"sessionId,omitempty"`
Payload json.RawMessage `json:"payload,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
}
func main() {
token := "eyJhbGciOiJIUzI1NiIs..."
u := url.URL{
Scheme: "wss",
Host: "api.orbai.world",
Path: "/ws/notifications",
RawQuery: fmt.Sprintf("token=%s", token),
}
conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("Connection failed:", err)
}
defer conn.Close()
// Subscribe to channels
subscribe := map[string]interface{}{
"type": "subscribe",
"channels": []string{"notification", "device_status", "server_alert"},
}
conn.WriteJSON(subscribe)
// Handle ping/pong
conn.SetPongHandler(func(appData string) error {
conn.SetReadDeadline(time.Now().Add(60 * time.Second))
return nil
})
// Graceful shutdown
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
done := make(chan struct{})
go func() {
defer close(done)
for {
var event Event
err := conn.ReadJSON(&event)
if err != nil {
log.Println("Read error:", err)
return
}
switch event.Type {
case "connection_ack":
fmt.Printf("Connected. Session: %s\n", event.SessionID)
case "notification":
fmt.Printf("[Notification] %s\n", string(event.Payload))
case "device_status":
fmt.Printf("[Device] %s\n", string(event.Payload))
case "server_alert":
fmt.Printf("[Alert] %s\n", string(event.Payload))
}
}
}()
select {
case <-done:
case <-interrupt:
log.Println("Shutting down...")
conn.WriteMessage(
websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""),
)
select {
case <-done:
case <-time.After(time.Second):
}
}
}نمونهٔ جریان تهدید OrbGuard
اتصال به جریان هوش تهدید OrbGuard بهجای JWT از احراز هویت با کلید API استفاده میکند.
// OrbGuard Threat Stream WebSocket
const apiKey = 'ogk_live_abc123...';
const ws = new WebSocket(
`wss://guard.orbai.world/ws/threats?api_key=${apiKey}`
);
ws.onopen = () => {
console.log('Connected to OrbGuard threat stream');
// Subscribe to specific threat categories
ws.send(JSON.stringify({
type: 'subscribe',
channels: ['threat_detected', 'alert'],
filters: {
severity: ['critical', 'high'],
categories: ['malware', 'phishing', 'c2'],
},
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'threat_detected') {
const threat = data.payload;
console.log(`[THREAT] ${threat.severity.toUpperCase()}`);
console.log(` Indicator: ${threat.indicator}`);
console.log(` Type: ${threat.indicatorType}`);
console.log(` Category: ${threat.category}`);
console.log(` Score: ${threat.score}/100`);
}
if (data.type === 'alert') {
const alert = data.payload;
console.log(`[ALERT] ${alert.title}`);
console.log(` ${alert.message}`);
console.log(` Action: ${alert.recommendedAction}`);
}
};راهبرد اتصال دوباره
گسست شبکه ناگزیر است. برای اتصال دوبارهٔ بیدردسر، عقبنشینی نمایی همراه با نوسان تصادفی پیاده کنید.
class ReconnectingWebSocket {
constructor(url, options = {}) {
this.url = url;
this.maxRetries = options.maxRetries || 10;
this.baseDelay = options.baseDelay || 1000; // 1 second
this.maxDelay = options.maxDelay || 30000; // 30 seconds
this.retryCount = 0;
this.handlers = {};
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
console.log('Connected');
this.retryCount = 0; // Reset on successful connection
this.handlers.open?.();
};
this.ws.onmessage = (event) => {
this.handlers.message?.(JSON.parse(event.data));
};
this.ws.onclose = (event) => {
if (event.code === 1000) return; // Normal closure
if (this.retryCount < this.maxRetries) {
const delay = Math.min(
this.baseDelay * Math.pow(2, this.retryCount) + Math.random() * 1000,
this.maxDelay
);
console.log(`Reconnecting in ${Math.round(delay)}ms (attempt ${this.retryCount + 1})`);
this.retryCount++;
setTimeout(() => this.connect(), delay);
} else {
console.error('Max reconnection attempts reached');
this.handlers.maxRetriesReached?.();
}
};
}
on(event, handler) {
this.handlers[event] = handler;
return this;
}
send(data) {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(data));
}
}
close() {
this.ws.close(1000, 'Client closing');
}
}
// Usage
const ws = new ReconnectingWebSocket(
`wss://api.orbai.world/ws/notifications?token=${token}`,
{ maxRetries: 10, baseDelay: 1000 }
);
ws.on('open', () => {
ws.send({ type: 'subscribe', channels: ['notification'] });
});
ws.on('message', (data) => {
console.log('Event:', data);
});ضربان / پینگ-پنگ
سرور هر ۳۰ ثانیه قاب پینگ وبسوکت میفرستد. کلاینتها باید با قاب پنگ پاسخ دهند. اگر ظرف ۳۰ ثانیه پنگی نرسد، سرور اتصال را میبندد.
| پارامتر | مقدار |
|---|---|
| فاصلهٔ پینگ | ۳۰ ثانیه |
| مهلت پنگ | ۳۰ ثانیه |
| بیشینه پینگ ازدسترفته | ۱ (اتصال پس از ۱ پنگ ازدسترفته بسته میشود) |
| پینگ آغازشده از سوی کلاینت | پشتیبانی میشود (سرور با پنگ پاسخ میدهد) |
وبسوکت مرورگر
بیشتر پیادهسازیهای وبسوکت در مرورگرها قابهای پینگ-پنگ را خودکار در سطح پروتکل مدیریت میکنند. تنها هنگام استفاده از کتابخانههای سطحپایین وبسوکت در زبانهای سمت سرور لازم است این را صریح مدیریت کنید.
قالب پیام رویداد
همهٔ رویدادهای وبسوکت از قالب یکسان JSON پیروی میکنند:
{
"type": "notification",
"id": "evt_abc123def456",
"timestamp": "2026-02-08T12:00:00.000Z",
"payload": {
"title": "Subscription Renewed",
"message": "Your OrbVPN Premium plan has been renewed for 12 months.",
"category": "billing",
"priority": "normal",
"metadata": {
"planName": "Premium",
"amount": 99.99,
"currency": "USD"
}
}
}| فیلد | نوع | توضیح |
|---|---|---|
type | string | گونهٔ رویداد (با نام کانال مشترکشده جور است) |
id | string | شناسهٔ یکتای رویداد برای حذف تکراریها |
timestamp | string | مُهر زمانی ISO 8601 لحظهٔ ساخته شدن رویداد |
payload | object | دادهٔ ویژهٔ رویداد (بسته به گونهٔ رویداد متفاوت است) |
سقف اتصالها
سقف اتصالها
اتصالهای وبسوکت برای هر حساب و هر نقطهٔ پایانی محدودند:
- اعلانها: ۵ اتصال همزمان برای هر کاربر
- گفتوگو: ۳ اتصال همزمان برای هر کاربر
- جریان تهدید: ۲ اتصال همزمان برای هر کلید API
- مجموع هر حساب: ۱۰ اتصال همزمان وبسوکت
گذر از این سقفها قاب بستن 4008 Connection Limit Reached را برمیگرداند. اتصالهای موجود متأثر نمیشوند.
کدهای بستن با خطا
اتصالهای وبسوکت ممکن است با کدهای زیر بسته شوند:
| کد | دلیل | اقدام |
|---|---|---|
1000 | بستن عادی | اقدامی لازم نیست |
1001 | سرور در حال کنار رفتن | با عقبنشینی دوباره وصل شوید |
1008 | نقض سیاست | گواهیهای احراز هویت را بررسی کنید |
1011 | خطای داخلی سرور | با عقبنشینی دوباره وصل شوید |
4001 | احراز هویت ناکام ماند | رمزینه را تازه کنید و دوباره وصل شوید |
4003 | ممنوع | مجوزهای کانال درخواستشده را بررسی کنید |
4008 | رسیدن به سقف اتصال | پیش از اتصال دوباره یکی از اتصالهای موجود را ببندید |
4029 | محدودشده به دلیل نرخ | به اندازهٔ مدت مشخصشده در دلیل بستن صبر کنید، سپس دوباره وصل شوید |
بهترین شیوهها
همیشه نخست احراز هویت کنید
رمزینهٔ خود را در نشانی اتصال یا پیام اولیه بدهید. هرگز پیش از رویداد connection_ack دادهٔ حساس نفرستید.
گزینشی مشترک شوید
تنها در کانالهایی مشترک شوید که لازم دارید. اشتراکهای گسترده پهنای باند و سربار پردازش را بالا میبرند.
رویدادهای تکراری را حذف کنید
برای حذف تکراریها از فیلد شناسهٔ رویداد استفاده کنید. هنگام اتصال دوباره ممکن است رویدادهایی بگیرید که پیشتر تحویل شدهاند.
فشار برگشتی را مدیریت کنید
رویدادهای ورودی را بافر کنید و ناهمزمان پردازششان کنید. رسیدگیکنندهٔ پیام وبسوکت را با عملیات کند مسدود نکنید.
بیدرنگ شوید
با APIهای وبسوکت اوربیویپیان، اعلانهای زنده، گفتوگو و هوش تهدید را در برنامهٔ خود یکپارچه کنید. تأخیر کم، قابلیت اتکای بالا و معماری سادهٔ رویدادمحور.