نکته مهم: اگر تماس اصلاً Register نمیشود یا INVITE به مقصد نمیرسد، هنوز وارد مرحله عیبیابی Media نشدهاید. این راهنما برای شرایطی است که Signaling حداقل تا حد زیادی سالم است و مشکل اصلی «نبود صدا»، «صدای یکطرفه» یا «قطع Media بعد از برقراری تماس» است.
اول مشخص کنیم «صدا ندارد» دقیقاً یعنی چه
سه وضعیت ظاهراً مشابه، علتهای متفاوتی دارند.
| نشانه | احتمال بیشتر |
|---|---|
| هیچکدام از طرفین صدا ندارند | ICE، DTLS، RTP Firewall یا Media Negotiation |
| فقط یک طرف صدا دارد | NAT، SDP، Candidate Pair یا Routing یکطرفه |
| Packet دریافت میشود ولی چیزی شنیده نمیشود | Codec، Audio Element، Output Device، Mute یا Autoplay مرورگر |
| ICE روی Checking میماند | Connectivity و STUN/TURN |
| ICE Connected است ولی Media نمیآید | DTLS-SRTP، RTP Routing یا Codec |
مسیر واقعی یک تماس WebRTC را بشناسید
در یک تماس مرورگری روی Asterisk، دو مسیر مستقل داریم.
Signaling:
Browser
|
| WSS / SIP
v
Asterisk
Media:
Browser
|
ICE Candidate Selection
|
DTLS Handshake
|
SRTP
|
Asterisk
بنابراین ممکن است:
REGISTER = موفق
INVITE = موفق
200 OK = موفق
ACK = موفق
ولی:
ICE یا DTLS شکست بخورد و هیچ صدایی نداشته باشید.
روش تشخیص استاندارد مشکل WebRTC no audio
این ترتیب را حفظ کنید:
مرحله ۱: آیا Browser Microphone Track دارد؟
مرحله ۲: آیا ICE Candidate جمعآوری شده است؟
مرحله ۳: کدام Candidate Pair انتخاب شده؟
مرحله ۴: آیا ICE به Connected یا Completed رسیده؟
مرحله ۵: آیا DTLS Handshake موفق شده؟
مرحله ۶: آیا SRTP Packet ارسال میشود؟
مرحله ۷: آیا Asterisk RTP دریافت و ارسال میکند؟
مرحله ۸: آیا Browser Packet دریافت میکند ولی Audio را پخش نمیکند؟
مرحله ۱: قبل از ICE، Microphone مرورگر را بررسی کنید
اگر Browser اصلاً Audio Track تولید نکرده باشد، بررسی TURN و RTP هیچ کمکی نمیکند.
در DevTools Console میتوانید سادهترین تست را اجرا کنید:
navigator.mediaDevices
.getUserMedia({
audio: true,
video: false
})
.then(stream => {
console.log(stream.getAudioTracks());
})
.catch(err => {
console.error(err.name, err.message);
});
اگر Audio Track دارید، به مرحله ICE بروید.
اگر ندارید، موارد زیر را بررسی کنید:
🔹 Permission میکروفن Browser روی Block نباشد.
🔹 Web App با HTTPS اجرا شود.
🔹 دستگاه ورودی مناسب انتخاب شده باشد.
🔹 برنامه دیگری Microphone را انحصاری نگرفته باشد.
مرحله ۲: ICE Candidateها را بررسی کنید
ICE قبل از برقراری Media چند مسیر احتمالی برای ارتباط پیدا میکند.
Candidateهای مهم WebRTC چهار نوع هستند:
| نوع | معنی | در عیبیابی چه میگوید؟ |
|---|---|---|
| host | آدرس مستقیم Interface | برای LAN یا مسیر مستقیم مناسب است |
| srflx | Server Reflexive | Public Mapping کشفشده از طریق STUN |
| prflx | Peer Reflexive | Mapping کشفشده حین Connectivity Check |
| relay | TURN Relay | Media از TURN Server عبور میکند |
نمونه Candidate از نوع host
a=candidate:4234997325 1 udp 2043278322 192.0.2.172 44323 typ host
بخش آخر:
typ host
نوع Candidate را مشخص میکند.
اگر فقط host Candidate دارید چه؟
اگر Browser و Asterisk در دو شبکه متفاوت یا پشت NAT باشند، Candidate محلی بهتنهایی اغلب کافی نیست.
مثلاً Browser میگوید:
192.168.1.42:53188
اما Asterisk اینترنتی طبیعتاً نمیتواند مستقیماً به این آدرس خصوصی Route کند.
در چنین شرایطی باید حداقل Candidate مناسب STUN یا TURN وجود داشته باشد.
srflx یعنی STUN کار کرده است؟
وجود Candidate از نوع `srflx` معمولاً نشان میدهد ICE Agent توانسته Public Mapping مربوط به NAT را کشف کند.
مثلاً:
typ srflx
address: 198.51.100.24
relatedAddress: 192.168.1.42
اما وجود `srflx` به معنی تضمین ارتباط نیست.
ممکن است NAT اجازه برگشت Packet از Peer را ندهد و Connectivity Check شکست بخورد.
relay مهمترین Candidate برای تشخیص TURN است
اگر Candidate از نوع:
typ relay
میبینید، TURN Server توانسته Relay Candidate ایجاد کند.
این Candidate زمانی بسیار مهم است که Direct Connectivity از طریق host یا srflx ممکن نباشد.
نبود relay Candidate همیشه مشکل نیست
اگر Direct Candidate کار میکند، WebRTC ممکن است اصلاً به TURN نیاز نداشته باشد.
بنابراین قانون درست این نیست:
«relay نداریم پس WebRTC خراب است.»
قانون درست این است:
«اگر Direct Candidate شکست میخورد، آیا یک relay Candidate سالم برای مسیر جایگزین داریم؟»
مرحله ۳: Selected Candidate Pair را پیدا کنید
صرف وجود Candidate کافی نیست.
ICE در نهایت یک جفت Candidate را انتخاب میکند.
مثلاً:
Local:
relay / UDP
Remote:
host / UDP
State:
succeeded
این اطلاعات بسیار مهمتر از فهرست تمام Candidateهاست.
کجا Candidate Pair را ببینیم؟
در مرورگرهای Chromium میتوانید از WebRTC Internals یا ابزارهای Developer مربوط به PeerConnection استفاده کنید.
در برنامه خودتان نیز `getStats()` اطلاعات دقیقی میدهد.
نمونه ساده getStats
const stats = await peerConnection.getStats();
stats.forEach(report => {
if (
report.type === "candidate-pair" ||
report.type === "inbound-rtp" ||
report.type === "outbound-rtp"
) {
console.log(report);
}
});
چه چیزهایی را در Stats نگاه کنیم؟
برای Media ورودی:
🔹 packetsReceived
🔹 bytesReceived
🔹 packetsLost
🔹 jitter
برای خروجی:
🔹 packetsSent
🔹 bytesSent
اگر bytesSent بالا میرود ولی bytesReceived صفر است
این یکی از واضحترین نشانههای Media یکطرفه است.
یعنی Browser صدا میفرستد، اما Media برگشتی به Browser نمیرسد.
تمرکز روی:
🔹 NAT سمت Asterisk
🔹 Firewall
🔹 SDP Address
🔹 Remote Candidate
🔹 RTP Routing
قرار میگیرد.
اگر bytesReceived بالا میرود ولی کاربر صدایی نمیشنود
شبکه احتمالاً کار میکند.
حالا Browser Playback را بررسی کنید:
🔹 آیا Remote Stream به Audio Element وصل شده؟
🔹 آیا Audio Element روی mute نیست؟
🔹 آیا Output Device درست انتخاب شده؟
🔹 آیا Browser به دلیل Autoplay Policy، `play()` را متوقف کرده است؟
یک خطای برنامهنویسی رایج
ممکن است Track از شبکه رسیده باشد ولی هیچ Media Elementی آن را پخش نکند.
ساختار ساده:
peerConnection.ontrack = event => {
const remoteAudio = document.getElementById("remoteAudio");
remoteAudio.srcObject = event.streams[0];
remoteAudio.play().catch(error => {
console.error("Audio playback blocked:", error);
});
};
مرحله ۴: وضعیت ICE را بررسی کنید
مقادیر مهم `iceConnectionState` عبارتاند از:
🔹 new
🔹 checking
🔹 connected
🔹 completed
🔹 disconnected
🔹 failed
🔹 closed
اگر روی checking گیر کرده است
Candidateها جمع شدهاند اما هیچ Candidate Pair موفقی پیدا نشده است.
علتهای رایج:
🔹 UDP بین دو طرف Block شده است.
🔹 NAT اجازه ارتباط مستقیم نمیدهد.
🔹 STUN Candidate قابلاستفاده نیست.
🔹 TURN Relay ندارید.
🔹 TURN Authentication شکست خورده است.
اگر ICE روی failed میرود
ICE Connectivity Checkها شکست خوردهاند.
در این حالت قبل از بررسی Codec و Dialplan، مشکل Connectivity را برطرف کنید.
Codec باعث نمیشود ICE State به failed برود.
اگر ICE connected است ولی هنوز صدا ندارید
این مرحله بسیار مهم است.
وقتی ICE Connected شده، حداقل یک مسیر Network بین دو طرف پیدا شده است.
حالا باید به ترتیب بررسی کنید:
DTLS → SRTP → Codec → Browser Playback
TURN چه زمانی مشکل را حل میکند؟
TURN زمانی وارد کار میشود که ارتباط مستقیم میان Browser و مقصد ممکن یا پایدار نباشد.
بهجای:
Browser ↔ Asterisk
مسیر تبدیل میشود به:
Browser
|
TURN Relay
|
Asterisk
سناریویی که TURN اهمیت زیادی پیدا میکند
فرض کنید WebRTC برای کاربران اینترنت خانگی کار میکند اما کاربران یک شرکت خاص هیچ صدایی ندارند.
این الگو میتواند نشان دهد:
🔹 Firewall سازمان UDP را محدود کرده است.
🔹 NAT سختگیرانه است.
🔹 Direct ICE Candidate شکست میخورد.
اگر TURN روی مسیر سازگار در دسترس باشد، `relay` Candidate میتواند اتصال را برقرار کند.
چطور مطمئن شویم TURN واقعاً استفاده میشود؟
بهترین پاسخ:
Selected Candidate Pair را ببینید.
اگر Candidate انتخابشده:
type = relay
باشد، Media از TURN استفاده میکند.
روش تست مهم: فقط TURN را اجباری کنید
برای عیبیابی موقت میتوانید در Browser فقط Relay Candidate را اجازه دهید:
const configuration = {
iceServers: [
{
urls: "turn:turn.example.com:3478",
username: "TEMP_USER",
credential: "TEMP_PASSWORD"
}
],
iceTransportPolicy: "relay"
};
const pc = new RTCPeerConnection(configuration);
این تنظیم برای تست بسیار ارزشمند است.
اگر تماس در حالت `relay` کاملاً صدا دارد ولی در حالت عادی ندارد، مشکل احتمالاً در Direct ICE/NAT Path است.
relay را دائماً Force کنیم؟
نه لزوماً.
TURN تمام Media را از سرور عبور میدهد و در نتیجه:
🔹 Bandwidth سرور افزایش پیدا میکند.
🔹 یک Hop جدید به تماس اضافه میشود.
🔹 Latency ممکن است افزایش یابد.
در بیشتر سیستمها TURN باید مسیر جایگزین قابلاعتماد باشد، مگر اینکه طراحی امنیتی شما عمداً Media Relay اجباری بخواهد.
Coturn برای TURN Server
یکی از رایجترین گزینههای متنباز برای STUN/TURN، پروژه Coturn است.
TURN Server باید Authentication داشته باشد و Anonymous Relay برای سرویس عمومی انتخاب امنی نیست.
برای WebRTC میتوان از Long-Term Credential یا Credentialهای زماندار استفاده کرد.
TURN Credential را داخل JavaScript دائمی Hardcode نکنید
اگر Web App عمومی است، هر کاربر میتواند Source را ببیند.
یک Password دائمی TURN داخل JavaScript عملاً Secret نیست.
برای سرویس واقعی بهتر است Credential زماندار از Backend صادر شود.
پورتهای TURN
Coturn بهصورت رایج Listenerهایی مثل:
3478
5349
دارد، اما Relay Media Portها نیز باید در Firewall مطابق `min-port` و `max-port` واقعی سرور باز باشند.
این نکته یکی از علتهای کلاسیک «TURN وصل میشود ولی Media عبور نمیکند» است.
TURN Server پشت NAT است؟
اگر خود Coturn پشت NAT قرار دارد، Public/External IP باید بهدرستی تنظیم شود.
در غیر این صورت Relay Candidate ممکن است آدرسی تبلیغ کند که Browser یا Asterisk نمیتوانند به آن دسترسی داشته باشند.
یک مقاله مرتبط در ایرانیکاسرور
اگر هنوز TURN Server ندارید: در مقاله راهاندازی Coturn روی VPS ایران میتوانید نمونه عملی ساخت TURN Server را ببینید. برای WebRTC تلفنی نیز همان مفاهیم Public IP، Authentication، Relay Port و Firewall اهمیت دارند.
مرحله ۵: DTLS را بررسی کنید
بعد از پیدا شدن مسیر ICE، WebRTC باید Media Encryption را آماده کند.
در معماری معمول Browser و Asterisk، این مرحله با:
DTLS-SRTP
انجام میشود.
DTLS چه کاری میکند؟
DTLS روی مسیر Datagram اجرا میشود و در WebRTC برای مذاکره کلیدهای SRTP استفاده میشود.
خود Audio بعداً به شکل SRTP منتقل میشود.
پس:
ICE = مسیر شبکه
DTLS = مذاکره امنیت Media
SRTP = صدای رمزنگاریشده
در SDP دنبال چه چیزی بگردیم؟
وجود Fingerprint:
a=fingerprint:sha-256 ...
و Setup Role:
a=setup:actpass
از نشانههای مهم DTLS هستند.
Asterisk WebRTC و DTLS
در PJSIP، اگر Endpoint شما:
webrtc=yes
داشته باشد، Asterisk تنظیمات اصلی WebRTC مانند:
use_avpf=yes
media_encryption=dtls
dtls_verify=fingerprint
dtls_setup=actpass
ice_support=yes
media_use_received_transport=yes
rtcp_mux=yes
را فعال میکند.
اگر ICE Connected است ولی DTLS شکست میخورد
علتهای محتمل:
🔹 Endpoint WebRTC بهدرستی تعریف نشده است.
🔹 Fingerprint بین SDP دو طرف سازگار نیست.
🔹 DTLS Certificate/Private Key قابل استفاده نیست.
🔹 SDP توسط SBC/Proxy نامناسب تغییر کرده است.
🔹 Packetهای DTLS روی مسیر Media Drop میشوند.
WSS Certificate را با DTLS Certificate اشتباه نگیرید
این خطا بسیار رایج است.
Certificate مربوط به:
wss://pbx.example.com:8089/ws
برای Signaling است.
DTLS Media نیز Certificate/Fingerprint خودش را دارد.
ممکن است WSS کاملاً سالم باشد و DTLS Media شکست بخورد.
مرحله ۶: RTP را روی Asterisk ببینید
اگر Asterisk دارید، ابتدا SIP Logger:
pjsip set logger on
و سپس RTP Debug:
rtp set debug on
را فقط هنگام تست کوتاه فعال کنید؛ روی سرور پرترافیک Output آن میتواند بسیار زیاد شود.
چه نتیجهای مهم است؟
سه حالت داریم.
حالت اول: Asterisk هیچ Media Packet دریافت نمیکند
مشکل احتمالاً قبل از Asterisk است:
🔹 ICE Pair
🔹 TURN
🔹 NAT
🔹 Firewall
🔹 Candidate Address
حالت دوم: Asterisk Packet دریافت میکند ولی برنمیگرداند
بررسی کنید:
🔹 Media Destination
🔹 Codec Negotiation
🔹 Bridge State
🔹 Route خروجی
حالت سوم: Asterisk هم Send و هم Receive دارد
اگر Browser هنوز بیصداست، روی:
🔹 Selected Candidate Pair
🔹 Browser getStats
🔹 Remote Track
🔹 Audio Playback
تمرکز کنید.
Packet Capture روی Server
برای Range نمونه RTP Asterisk:
tcpdump -ni any udp portrange 10000-20000
اگر در `rtp.conf` Range دیگری دارید، همان مقدار واقعی را استفاده کنید.
Capture کاملتر برای یک Client خاص
tcpdump -ni any host 198.51.100.25 -w /tmp/webrtc-media.pcap
IP مثال است.
فایل را بعداً در Wireshark بررسی کنید.
در WebRTC Packet Capture همیشه RTP خوانا نیست
Media مرورگر معمولاً SRTP است.
بنابراین در Wireshark ممکن است Packetها را ببینید ولی Payload صوت مستقیماً Decode نشود.
برای تشخیص اولیه همین سؤال مهم است:
آیا Packet دوطرفه عبور میکند یا خیر؟
مرحله ۷: NAT روی Asterisk را بررسی کنید
اگر Asterisk خودش پشت NAT است، Network Configuration باید Public Address را درست Advertise کند.
در PJSIP Transport معمولاً مواردی مانند:
external_signaling_address=
external_media_address=
local_net=
با توجه به Topology شبکه اهمیت دارند.
مقدار دقیق را از شبکه خودتان بگیرید؛ Public IP یا CIDR نمونه اینترنت را Copy نکنید.
علامت کلاسیک NAT اشتباه
اگر در SDP سمت اینترنت هنوز چیزی شبیه:
c=IN IP4 10.10.0.15
میبینید و Client اینترنتی قرار است Media مستقیم بفرستد، Topology را دوباره بررسی کنید.
WebRTC با ICE همیشه فقط از c= خط SDP پیروی نمیکند
این نکته مهم است.
در WebRTC، ICE Candidateها تعیینکننده اصلی Connectivity هستند.
پس فقط خط:
c=IN IP4 ...
را نبینید؛ Candidateها و Selected Pair را هم بررسی کنید.
مرحله ۸: Firewall را بر اساس Packet بررسی کنید
برای رفع سریع مشکل، کل Firewall را خاموش نکنید.
اول مشخص کنید:
Packet باید از کجا وارد شود؟
روی چه Portی؟
به کدام مقصد؟
بعد فقط Rule لازم را اصلاح کنید.
Firewallهای درگیر ممکن است چندتا باشند
🔹 Firewall خود Server
🔹 Cloud Firewall یا Security Group
🔹 Router/NAT Gateway
🔹 Firewall سازمان کاربر
🔹 Firewall TURN Server
یک اشتباه رایج TURN
Port 3478 باز است.
Browser حتی میتواند Allocate Request انجام دهد.
اما Relay UDP Port Range روی Firewall بسته است.
نتیجه:
TURN ظاهراً Online است ولی Media عبور نمیکند.
مرحله ۹: Codec را بعد از Network بررسی کنید
اگر ICE و DTLS سالم هستند و Packet وجود دارد، Codec اهمیت پیدا میکند.
WebRTC معمولاً با Opus بسیار خوب کار میکند.
مثلاً Endpoint Asterisk:
disallow=all
allow=opus,ulaw,alaw
اگر هیچ Codec مشترکی وجود نداشته باشد
معمولاً Call Setup یا SDP Negotiation به مشکل میخورد و ممکن است Responseهایی مثل 488 ببینید.
اما اگر تماس برقرار است و Packet وجود دارد، Codec Negotiation و Decoder/Playback را همچنان بررسی کنید.
چرا مشکل فقط در تماس Browser به SIP Trunk دیده میشود؟
ممکن است Browser با:
Opus + DTLS-SRTP
و Carrier با:
PCMA + RTP
کار کند.
در نتیجه Asterisk یا Media Proxy باید بین دو Media Profile تطبیق ایجاد کند.
اگر RTPengine دارید چه؟
وقتی RTPengine بین WebRTC و Asterisk یا SIP Trunk قرار دارد، Media Troubleshooting یک Layer دیگر پیدا میکند.
مسیر:
Browser
|
ICE / DTLS-SRTP
|
RTPengine
|
RTP/SRTP
|
Asterisk
است.
باید هر Leg جداگانه بررسی شود.
اشتباه رایج با RTPengine
SDP هم روی Asterisk و هم روی RTPengine با Policyهای متناقض Rewrite میشود.
در چنین حالتی Media Address یا ICE Candidate ممکن است غیرمنتظره شود.
از ابتدا مشخص کنید مالک Media NAT و SDP Rewrite کدام Layer است.
اگر تماس پس از ۳۰ ثانیه قطع میشود
این الزاماً همان مشکل «no audio» نیست.
قطع نزدیک ۳۰ ثانیه معمولاً شما را دوباره به Signaling و ACK/Transaction هدایت میکند.
پس دو مشکل را یکی نکنید:
تماس برقرار و بیصدا
با:
تماس بعد از مدت ثابت قطع میشود
مسیر عیبیابی یکسانی ندارند.
اگر فقط صدای ورودی نداریم
از Browser شروع کنید.
در `getStats()` ببینید:
inbound-rtp → packetsReceived
آیا افزایش پیدا میکند؟
اگر صفر است، Media به Browser نمیرسد.
اگر افزایش دارد، Playback را بررسی کنید.
اگر فقط صدای خروجی نداریم
بررسی کنید:
🔹 Local Audio Track وجود دارد.
🔹 Track روی enabled است.
🔹 Sender به PeerConnection اضافه شده است.
🔹 outbound-rtp packetsSent افزایش پیدا میکند.
نمونه بررسی Track محلی
const senders = peerConnection.getSenders();
senders.forEach(sender => {
if (sender.track) {
console.log(
sender.track.kind,
sender.track.enabled,
sender.track.readyState
);
}
});
readyState روی ended است؟
اگر Microphone Track پایان یافته باشد، PeerConnection میتواند هنوز برقرار باشد ولی Audio جدیدی ارسال نشود.
این موضوع مخصوصاً بعد از تغییر Audio Device یا Reconnect کردن Headset قابل بررسی است.
یک Decision Tree سریع
تماس بیصداست.
آیا ICE Connected است؟
🔹 خیر → Candidate، STUN، TURN، NAT و Firewall.
🔹 بله → DTLS را بررسی کنید.
آیا DTLS موفق است؟
🔹 خیر → Fingerprint، Certificate، SDP و Media Path.
🔹 بله → RTP/SRTP Packet را بررسی کنید.
Packet به Browser میرسد؟
🔹 خیر → Routing، Firewall، NAT، TURN.
🔹 بله → Codec، Remote Track، Audio Element و Output Device.
سناریوی ۱: روی Wi-Fi خانه کار میکند ولی روی اینترنت موبایل نه
احتمال زیاد باید ICE Path دو شبکه را مقایسه کنید.
روی Mobile ممکن است CGNAT متفاوتی وجود داشته باشد.
Selected Candidate Pair را روی هر دو اتصال ثبت کنید.
اگر Wi-Fi از `srflx` و Mobile فقط با `relay` کار میکند، TURN برای این کاربران ضروری است.
سناریوی ۲: داخل شرکت کار نمیکند ولی بیرون شرکت سالم است
موارد احتمالی:
🔹 Corporate Firewall
🔹 UDP Restriction
🔹 TLS Inspection
🔹 Proxy Policy
TURN روی Transport مناسب میتواند مسیر جایگزین ایجاد کند.
سناریوی ۳: TURN Candidate ساخته نمیشود
بررسی کنید:
🔹 TURN Hostname Resolve میشود؟
🔹 Credential معتبر است؟
🔹 Listener Port در دسترس است؟
🔹 Realm و Authentication درست است؟
🔹 Browser Console خطای ICE Candidate نشان میدهد؟
روی TURN Server Portها را ببینید
ss -lntup | grep -E '3478|5349'
سناریوی ۴: relay Candidate داریم ولی باز هم صدا نیست
وجود Candidate به معنی کاملشدن مسیر نیست.
بررسی کنید:
آیا همان relay Candidate در Selected Pair استفاده شده است؟
اگر بله:
🔹 Relay Port Range باز است؟
🔹 TURN Server به Asterisk دسترسی دارد؟
🔹 Public/External IP درست Advertise شده؟
🔹 DTLS بعد از ICE موفق شده؟
سناریوی ۵: ICE Completed ولی Packet Loss صددرصد است
Connectivity Check موفق شده ولی مسیر Media واقعی ممکن است مشکل داشته باشد.
Capture دو سمت را مقایسه کنید.
فقط به State مرورگر اعتماد نکنید.
سناریوی ۶: صدا چند ثانیه میآید و بعد قطع میشود
این الگو میتواند به:
🔹 NAT Mapping Timeout
🔹 Firewall State
🔹 ICE Restart
🔹 Network Handover
مربوط باشد.
Timeline مرورگر و Server Packet Capture را کنار هم بگذارید.
سناریوی ۷: کاربر صدا میشنود ولی Asterisk چیزی دریافت نمیکند
اگر صدای دریافتی Browser از سمت دیگری میآید ولی Media خروجی Browser به Asterisk نمیرسد، Local Track و outbound-rtp را بررسی کنید.
ممکن است مشکل اصلاً شبکه نباشد و Microphone Track ارسال نشده باشد.
از `connectionState` هم استفاده کنید
`RTCPeerConnection.connectionState` وضعیت کلی Peer Connection را نشان میدهد.
مقادیر مهم:
🔹 connecting
🔹 connected
🔹 disconnected
🔹 failed
اما برای تشخیص Media بهتر است در کنار آن:
`iceConnectionState` و Statistics واقعی RTP
را هم ببینید.
Logging ساده سمت Browser
peerConnection.addEventListener(
"iceconnectionstatechange",
() => {
console.log(
"ICE:",
peerConnection.iceConnectionState
);
}
);
peerConnection.addEventListener(
"connectionstatechange",
() => {
console.log(
"Connection:",
peerConnection.connectionState
);
}
);
برای Production چه چیزی Log کنیم؟
بدون ذخیره اطلاعات حساس، برای هر تماس ثبت کنید:
🔹 Call ID
🔹 ICE State
🔹 Selected Candidate Type
🔹 استفاده یا عدم استفاده از TURN
🔹 Codec انتخابشده
🔹 packetsSent/Received
🔹 packetsLost
🔹 jitter
این اطلاعات برای پیدا کردن الگوهای مشکل بین ISPها بسیار ارزشمند است.
در Log، IP خصوصی کاربران را بیدلیل نگه ندارید
ICE Diagnostics میتواند اطلاعات شبکه کاربر را آشکار کند.
Retention، Masking و دسترسی به Log را مطابق نیاز واقعی و سیاست حریم خصوصی طراحی کنید.
WebRTC no audio در معماری Asterisk + Kamailio + RTPengine
اگر معماری شما چندلایه است، مسیر را به Legهای کوچک تقسیم کنید.
Browser
|
WebRTC Media
|
RTPengine
|
RTP/SRTP
|
Asterisk
|
Carrier
نپرسید:
«چرا صدا نداریم؟»
بپرسید:
در کدام Leg اولین بار Packet ناپدید میشود؟
ترتیب Capture در معماری چندلایه
۱. Browser getStats
۲. RTPengine Interface سمت Browser
۳. RTPengine Interface سمت Asterisk
۴. Asterisk RTP Debug
۵. Carrier Leg
اولین جایی که Packet ورودی دارد ولی خروجی ندارد، محدوده مشکل را کوچک میکند.
چکلیست نهایی WebRTC بدون صدا
🔹 Microphone Permission فعال است.
🔹 Audio Track محلی ساخته شده است.
🔹 ICE Gathering کامل میشود.
🔹 Candidateهای منطقی وجود دارند.
🔹 در صورت نیاز relay Candidate داریم.
🔹 Selected Candidate Pair موفق است.
🔹 ICE Connected/Completed است.
🔹 DTLS Fingerprint وجود دارد.
🔹 DTLS Handshake موفق است.
🔹 RTP/SRTP Portهای لازم باز هستند.
🔹 Asterisk Packet دریافت و ارسال میکند.
🔹 Codec مشترک وجود دارد.
🔹 Browser Remote Track دریافت میکند.
🔹 Audio Element Muted نیست.
🔹 Output Device درست است.
پرسشهای رایج
چرا تماس WebRTC برقرار میشود اما صدا ندارد؟
چون Signaling و Media مسیرهای جدا دارند. ممکن است SIP و WSS کاملاً سالم باشند اما ICE، DTLS-SRTP، NAT، TURN، RTP Firewall یا پخش Audio مرورگر مشکل داشته باشد.
از کجا بفهمیم مشکل ICE است؟
اگر `iceConnectionState` روی `checking` بماند یا به `failed` برسد، ابتدا Candidateها، STUN، TURN، NAT و Firewall را بررسی کنید.
تفاوت host و srflx و relay چیست؟
host آدرس مستقیم Interface است، srflx معمولاً Public Mapping کشفشده از طریق STUN است و relay آدرسی است که TURN Server برای عبور Media در اختیار Connection قرار میدهد.
از کجا بفهمیم تماس واقعاً از TURN استفاده میکند؟
Selected Candidate Pair را بررسی کنید. اگر Candidate انتخابشده از نوع `relay` باشد، Media از TURN عبور میکند.
اگر relay Candidate نداریم یعنی TURN خراب است؟
اگر TURN در RTCConfiguration تعریف شده ولی هیچ relay Candidate ایجاد نمیشود، Credential، DNS، Listener Port، Firewall و تنظیمات TURN را بررسی کنید. اما اگر TURN اصلاً تعریف نشده یا Direct ICE موفق است، نبود relay الزاماً خطا نیست.
ICE Connected است ولی هنوز صدا نداریم؛ قدم بعد چیست؟
DTLS Handshake، SRTP Packetها، Codec و Browser Playback را بررسی کنید. ICE Connected فقط نشان میدهد یک مسیر ارتباطی پیدا شده است.
چرا صدا فقط یکطرفه است؟
معمولاً یکی از جهتهای RTP/SRTP بهدلیل NAT، Firewall، Candidate اشتباه یا Routing ناقص عبور نمیکند. bytesSent و bytesReceived در WebRTC Stats کمک زیادی میکنند.
آیا TURN مشکل همه NATها را حل میکند؟
TURN یک مسیر Relay بسیار مفید است، اما خود TURN نیز باید Public Reachability، Authentication، Relay Port Range و Routing درست داشته باشد.
DTLS چه ارتباطی با صدا دارد؟
در WebRTC، DTLS معمولاً برای مذاکره کلیدهای SRTP استفاده میشود. اگر ICE سالم باشد ولی DTLS Handshake شکست بخورد، Media رمزنگاریشده قابل راهاندازی نیست.
اگر Asterisk RTP دریافت میکند ولی Browser صدا ندارد چه؟
ببینید Asterisk RTP برگشتی ارسال میکند یا نه. اگر Browser نیز bytesReceived دارد، مشکل احتمالاً در Remote Track، Audio Element، Output Device یا Playback Policy مرورگر است.
آیا برای WebRTC حتماً TURN لازم است؟
خیر. در شبکههایی که Direct ICE با host یا srflx Candidate موفق میشود، TURN استفاده نمیشود. TURN برای شبکههایی که مسیر مستقیم ندارند بسیار مهم است.
جمعبندی
وقتی WebRTC تماس را برقرار میکند اما صدا ندارید، عیبیابی را از SIP شروع نکنید و همه تنظیمات را همزمان تغییر ندهید.
ابتدا مطمئن شوید مرورگر Audio Track دارد. سپس Candidateها را ببینید و مشخص کنید ICE کدام مسیر را انتخاب کرده است. اگر Direct Connection ممکن نیست، وجود و استفاده واقعی از Candidate نوع `relay` نشان میدهد TURN وارد مسیر شده است.
اگر ICE به Connected یا Completed میرسد، Connectivity اولیه برقرار است و باید DTLS-SRTP را بررسی کنید. بعد از موفقیت DTLS، سؤال اصلی این است که آیا RTP/SRTP Packet واقعاً دوطرفه حرکت میکند یا خیر.
در Asterisk از `pjsip set logger on` و `rtp set debug on` برای تست کنترلشده استفاده کنید و در Browser نیز `getStats()`، ICE State و Selected Candidate Pair را بررسی کنید.
اگر Packet به Browser میرسد ولی کاربر همچنان چیزی نمیشنود، دیگر TURN و Firewall مظنون اصلی نیستند؛ Remote Track، Audio Element، Mute، Output Device، Codec و Autoplay را بررسی کنید.
بهترین ترتیب عیبیابی این است:
Microphone → ICE Candidates → Selected Pair → TURN → DTLS → SRTP → RTP Stats → Browser Playback
با این ترتیب، مشکل «WebRTC no audio» از یک مسئله مبهم به چند مرحله قابلاندازهگیری تبدیل میشود.
WebRTC روی بعضی اینترنتها صدا ندارد؟ یک TURN Server مستقل با IP ثابت آزمایش کنید
اگر Web Phone شما روی یک شبکه کار میکند اما روی اینترنت موبایل، CGNAT یا شبکههای سازمانی بیصدا میشود، قبل از تغییر Asterisk یک TURN Server مستقل راهاندازی کنید و تماس را با `iceTransportPolicy: “relay”` آزمایش کنید. این تست خیلی سریع مشخص میکند مشکل از مسیر مستقیم NAT است یا باید جای دیگری دنبال علت بگردید.
برای کاربران داخل ایران، قرارگرفتن TURN و Media Node روی یک VPS ایران با IP ثابت میتواند مسیر کوتاهتری ایجاد کند. برای کاربران بینالمللی نیز بهتر است Location سرور به کاربران نزدیک باشد تا Relay باعث Latency اضافی نشود.
مشاوره Asterisk، Coturn، ICE و WebRTC: 021-91302467






دیدگاهها (۰)