Конфигурация сервера STUN/TURN для каналов Django с WebRTC
Я разработал с использованием каналов django для реализации видеочата и чата сообщений. (Я ссылался на курс YouTuber'а)
Когда я только закончил разработку, я заметил, что webrtc работает только в локальной сети, и обнаружил, что необходим сервер stun/turn
Итак, я создал отдельный EC2, построил сервер stun/turn и установил его на RTCPeerconnection в веб-сервере.
Тест сервера оглушения/поворота в Trickle ICE - это хорошо.
Но мой видеозвонок по-прежнему работает только в пределах локальной сети. И даже в пределах одной сети соединение было очень медленным.
Общая конфигурация сервера. (Веб-сервер с SSL-приложением loadbalancer)
Конфигурация поворота
# /etc/default/coturn
TURNSERVER_ENABLED=1
# /etc/turnserver.conf
# STUN server port is 3478 for UDP and TCP, and 5349 for TLS.
# Allow connection on the UDP port 3478
listening-port=3478
# and 5349 for TLS (secure)
tls-listening-port=5349
# Require authentication
fingerprint
lt-cred-mech
server-name=mysite.com
realm=mysite.com
# Important:
# Create a test user if you want
# You can remove this user after testing
user=myuser:userpassword
total-quota=100
stale-nonce=600
# Path to the SSL certificate and private key. In this example we will use
# the letsencrypt generated certificate files.
cert=/etc/letsencrypt/live/stun.mysite.com/cert.pem
pkey=/etc/letsencrypt/live/stun.mysite.com/privkey.pem
# Specify the allowed OpenSSL cipher list for TLS/DTLS connections
cipher-list="~~~~~-SHA512:~~~~~SHA512:~~~~~-SHA384:~~~~~SHA384:~~~-AES256-SHA384"
# Specify the process user and group
proc-user=turnserver
proc-group=turnserver
main.js в веб-сервере
код каналов django в веб-сервере
# Consumer.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
print('connect!!')
self.room_group_name = 'test_room'
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
print(f"room_group_name : {self.room_group_name} and channel_name : {self.channel_name}")
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
print('disconnected!')
async def receive(self, text_data):
receive_dict = json.loads(text_data)
print(f"receive_data : {receive_dict}")
message = receive_dict['message']
action = receive_dict['action']
if (action == 'new-offer') or (action == 'new-answer'):
receiver_channel_name = receive_dict['message']['receiver_channel_name']
receive_dict['message']['receiver_channel_name'] = self.channel_name
await self.channel_layer.send(
receiver_channel_name,
{
'type': 'send.sdp',
'receive_dict': receive_dict
}
)
return
receive_dict['message']['receiver_channel_name'] = self.channel_name
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'send.sdp',
'receive_dict': receive_dict
}
)
async def send_sdp(self, event):
print('send_sdp!!')
receive_dict = event['receive_dict']
await self.send(text_data=json.dumps(receive_dict))
# asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Project.settings')
django_asgi_app = get_asgi_application()
from channels.auth import AuthMiddlewareStack
import video_app.routing
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": AuthMiddlewareStack(
URLRouter(
video_app.routing.websocket_urlpatterns
)
),
})
#routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r"^ws/$", consumers.ChatConsumer.as_asgi()),
]
# settings.py
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("myredis.cache.amazonaws.com", 6379)]
},
},
}
В чем моя вина?