وب سوکت قیمت لحظه ای ارز لازم است یا REST؟ معماری درست برای اپهای مالی
وب سوکت قیمت لحظه ای ارز همیشه لازم نیست. مقایسهٔ WebSocket، REST Polling و Server-Sent Events برای نرخ ارز و طلا: تأخیر، هزینه، پیچیدگی و الگوی ترکیبی پیشنهادی.

- نرخ بازار آزاد ایران هر دقیقه محاسبه میشود؛ برای چنین دادهای REST Polling با کش، سادهتر و ارزانتر از WebSocket است.
- WebSocket وقتی ارزش دارد که داده در کسری از ثانیه تغییر کند، مثل دفتر سفارش صرافی رمزارز.
- الگوی پیشنهادی: سرور شما با REST از API بخواند و به کاربرانش با SSE یا WebSocket داخلی پخش کند.
وقتی صحبت از «قیمت لحظهای» میشود، خیلی از تیمها فوراً سراغ WebSocket میروند. اما انتخاب پروتکل باید از ماهیت داده شروع شود، نه از مد فنی. در این مقاله بررسی میکنیم وب سوکت قیمت لحظه ای ارز کجا لازم است و کجا فقط پیچیدگی اضافه میکند.
این مقاله بخشی از راهنمای کامل API قیمت ارز و طلا است.
سه روش انتقال دادهٔ لحظهای
| روش | نحوهٔ کار | جهت | نقطهٔ قوت | نقطهٔ ضعف |
|---|---|---|---|---|
| REST Polling | کلاینت هر N ثانیه درخواست میدهد | کلاینت ← سرور | ساده، قابل کش، سازگار با همهچیز | تأخیر تا N ثانیه |
| Server-Sent Events | یک اتصال HTTP باز؛ سرور رویداد میفرستد | سرور ← کلاینت | سادهتر از WebSocket، اتصال خودکار مجدد | یکطرفه |
| WebSocket | اتصال دوطرفهٔ دائمی | دوطرفه | کمترین تأخیر، مناسب دادههای پرتکرار | پیچیدگی، مدیریت اتصال، سختتر برای کش و پروکسی |
ماهیت دادهٔ نرخ ارز و طلای ایران
نرخ بازار آزاد تهران از پیامهای خرید و فروش گروهها، کانالها و صرافیها جمع میشود. معاملات واقعی ثانیهبهثانیه نیستند و هر نرخ معتبر حاصل میانهگیری چند منبع در یک بازهٔ زمانی است. در EZRate این محاسبه هر دقیقه انجام میشود (جزئیات در کشف قیمت دلار در بازار آزاد). پس اگر کلاینت شما هر ثانیه هم خبر بگیرد، عدد تازهتری از هر دقیقه دریافت نمیکند.
مقایسه کنید با دفتر سفارش یک صرافی رمزارز که در هر ثانیه دهها سفارش جدید ثبت میشود. آنجا WebSocket تقریباً اجباری است.
هزینههای پنهان WebSocket
- مقیاسپذیری: هر کاربر یک اتصال باز دارد. با ده هزار کاربر همزمان باید ده هزار اتصال را روی سرور نگه دارید.
- پروکسی و فایروال: برخی شبکههای سازمانی، اپراتورها و پروکسیها اتصالهای طولانی را قطع میکنند و باید منطق اتصال مجدد بنویسید.
- عدم کش: پاسخ REST را CDN و مرورگر کش میکنند؛ پیام WebSocket را نه.
- باتری موبایل: اتصال دائمی در اپ موبایل مصرف باتری را بالا میبرد.
الگوی ترکیبی پیشنهادی
برای اپ یا سایتی که میخواهد تغییر قیمت را «زنده» نشان دهد، بهترین معماری ترکیبی است:
- سرور شما هر ۶۰ ثانیه با REST از API نرخها را میگیرد (یک درخواست برای همهٔ کاربران).
- اگر عددی تغییر کرده بود، سرور تغییر را با SSE یا WebSocket داخلی خودش به کاربران متصل پخش میکند.
- کلاینتهایی که SSE ندارند (مثلاً ویجت ساده) همچنان هر ۶۰ ثانیه از سرور شما Polling میکنند.

// Node.js + Express: پخش تغییرات با Server-Sent Events
import express from "express"
const app = express()
const clients = new Set()
let last = {}
app.get("/rates/stream", (req, res) => {
res.set({ "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive" })
res.write(`data: ${JSON.stringify(last)}\n\n`) // آخرین وضعیت بلافاصله
clients.add(res)
req.on("close", () => clients.delete(res))
})
setInterval(async () => {
const r = await fetch("https://api.ezrate.me/v1/rates?symbols=usd,eur,g18,emami", {
headers: { "X-API-Key": process.env.EZRATE_KEY } })
if (!r.ok) return
const now = Object.fromEntries((await r.json()).data.map(x => [x.symbol, x.sell]))
if (JSON.stringify(now) !== JSON.stringify(last)) {
last = now
for (const c of clients) c.write(`data: ${JSON.stringify(now)}\n\n`)
}
}, 60_000)
app.listen(3000)در مرورگر هم سه خط کافی است: new EventSource("/rates/stream").onmessage = e => render(JSON.parse(e.data)). نسخهٔ انگلیسی با جزئیات بیشتر Node.js در WebSocket vs REST Polling آمده است.
جدول تصمیم
| سناریو | پیشنهاد |
|---|---|
| نمایش نرخ در سایت یا وبلاگ | ویجت یا REST با کش |
| اپ موبایل با صفحهٔ نرخ | REST هنگام باز بودن صفحه + Push برای هشدار |
| داشبورد معاملهگر با تغییرات زنده | REST در سرور + SSE به کاربران |
| دفتر سفارش صرافی رمزارز | WebSocket |
| هشدار قیمت | سرور بررسی کند و Push بفرستد؛ کلاینت متصل نماند |
تأخیر واقعی را اندازه بگیرید، نه حدس بزنید
پیش از هر تصمیم معماری، تأخیر سرتاسری سیستم خود را اندازه بگیرید: از لحظهای که نرخ در API تغییر میکند (updated_at) تا لحظهای که کاربر آن را میبیند. اغلب معلوم میشود گلوگاه پروتکل نیست؛ کش بیش از حد طولانی، CDN یا فاصلهٔ Polling کلاینت است. یک لاگ ساده کافی است:
const lag = (Date.now() - Date.parse(rate.updated_at)) / 1000
console.log(`${rate.symbol}: ${lag.toFixed(0)}s since the rate was computed`)اگر این عدد بهطور معمول زیر دو دقیقه است، کاربر شما تفاوتی با یک سیستم WebSocket حس نمیکند.
اپ موبایل: Push بهجای اتصال دائمی
در اپهای موبایل، کاربر بیشتر وقتها اپ را باز ندارد. چیزی که برایش مهم است، خبر شدن از تغییر مهم قیمت است، نه دیدن تغییر هر دقیقه. معماری درست: وقتی اپ باز است، صفحهٔ نرخ هر ۶۰ ثانیه از سرور شما تازه شود؛ وقتی بسته است، سرور شرطهای هشدار را بررسی کند و Push بفرستد. اپ EZRate و هشدار قیمت دقیقاً با همین الگو کار میکنند.
وقتی واقعاً WebSocket میخواهید
اگر محصول شما دفتر سفارش، معاملهٔ لحظهای یا چت دارد، WebSocket انتخاب درستی است. در این صورت هم دادهٔ نرخ بازار آزاد را از همان کانال WebSocket خود پخش کنید؛ یعنی سرور شما با REST از API میخواند و روی سوکت خودش به کاربران میفرستد. لازم نیست برای هر منبع داده یک پروتکل جدا داشته باشید.

نرخهای لحظهای مرتبط با این مطلب: قیمت دلار، قیمت طلای ۱۸ عیار، قیمت سکه امامی.

نظرات (۰)
نظرها پس از تأیید نمایش داده میشوند؛ برای ارسال، ورود به حساب لازم است.


