SDP (Session Description Protocol) là một định dạng văn bản để mô tả các phiên đa phương tiện, được thiết kế để thương lượng các tham số kết nối giữa các bên tham gia. Theo IETF RFC 8866 (2021), SDP định nghĩa cấu trúc mô tả các luồng phương tiện, codec, địa chỉ truyền tải và các tham số khác mà không truyền dữ liệu phương tiện. Giao thức này đã trở thành thành phần chính của WebRTC, cho phép trao đổi thông tin giữa trình duyệt và ứng dụng di động trước khi thiết lập kết nối peer-to-peer.
Những điểm chính
SDP là một giao thức lớp ứng dụng được thiết kế để mô tả các tham số phiên đa phương tiện ở định dạng văn bản. Nó được phát triển trong nhóm làm việc MMUSIC (Multiparty Multimedia Session Control) của IETF và được tiêu chuẩn hóa lần đầu tiên trong RFC 2327 vào năm 1998. Năm 2021, đặc tả hiện tại RFC 8866 đã được công bố, thay thế phiên bản trước RFC 4566.
Nhiệm vụ chính của SDP là cung cấp cho những người tham gia phiên tất cả thông tin cần thiết để thiết lập kết nối: luồng phương tiện nào sẽ được truyền, codec nào được hỗ trợ và qua địa chỉ mạng và cổng nào quá trình truyền sẽ diễn ra. SDP không truyền dữ liệu phương tiện mà chỉ mô tả cách tổ chức kết nối.
Theo IETF RFC 8866, định dạng SDP bao gồm một tập hợp các dòng, mỗi dòng bắt đầu bằng một loại một ký tự, theo sau là dấu bằng và một giá trị. Ví dụ, dòng m=audio 5004 RTP/AVP 0 có nghĩa là phiên bao gồm một luồng âm thanh trên cổng 5004 với giao thức truyền tải RTP/AVP và codec PCMU (loại 0).
Phiên bản đầu tiên của SDP được công bố trong RFC 2327 vào tháng 4 năm 1998 như kết quả của nhóm MMUSIC. Giao thức ban đầu được tạo ra để thông báo các phiên multicast trong Mbone (Multicast Backbone). Với sự phát triển của VoIP và hội nghị truyền hình, phạm vi ứng dụng của SDP đã mở rộng và vào năm 2006, đặc tả cập nhật RFC 4566 đã được công bố.
Một bước đột phá thực sự trong việc sử dụng SDP đã xảy ra với sự ra đời của WebRTC vào năm 2011. Google đã tích hợp SDP như cơ chế chính để mô tả các phiên phương tiện trong framework giao tiếp thời gian thực dựa trên trình duyệt của mình. Kể từ đó, SDP đã trở thành thành phần bắt buộc của mọi triển khai WebRTC — từ trình duyệt đến ứng dụng di động trên iOS và Android.
Năm 2021, nhóm làm việc IETF đã công bố RFC 8866 — đặc tả SDP hiện tại, thay thế RFC 4566. Phiên bản cập nhật đã làm rõ xử lý ICE (Interactive Connectivity Establishment), hỗ trợ DTLS (Datagram Transport Layer Security) và mở rộng khả năng mô tả các phiên nhóm.
SDP khác cơ bản với các giao thức truyền tải ở chỗ nó không tham gia vào việc truyền dữ liệu. Nó thực hiện chức năng mô tả thuần túy — tương tự như siêu dữ liệu của tệp đa phương tiện. Trong khi RTP (Real-time Transport Protocol) truyền các gói âm thanh và video, RTCP kiểm soát chất lượng truyền, thì SDP chỉ chỉ định codec và cổng nào sẽ sử dụng.
Một phép tương tự từ phát triển web: SDP giống như mã HTML mô tả cấu trúc trang, trong khi RTP là hình ảnh và văn bản thực tế. Không có SDP, những người tham gia phiên không biết cách kết nối với nhau, ngay cả khi kết nối mạng đã được thiết lập. Cơ chế NAT traversal (ICE) cũng dựa vào SDP để truyền thông tin về các ứng viên mạng.
Cấu trúc SDP được tổ chức dưới dạng một chuỗi các dòng văn bản, mỗi dòng tuân theo định dạng type=value. Loại một ký tự xác định mục đích của dòng và giá trị chứa giá trị tương ứng. Tất cả các dòng được phân tách bằng ký tự CRLF.
Tiêu chuẩn RFC 8866 định nghĩa một số trường bắt buộc và tùy chọn. Các trường bắt buộc bao gồm phiên bản giao thức (v=), tên phiên (s=) và thời gian bắt đầu và kết thúc phiên (t=). Các trường còn lại là tùy chọn, nhưng đối với các phiên WebRTC, mô tả phương tiện (m=), thuộc tính (a=) và thông tin mạng (c=) cũng cần thiết.
v=0
o=- 46116397 2 IN IP4 192.168.1.100
s=-
t=0 0
a=group:BUNDLE audio video
m=audio 5004 RTP/SAVPF 111 103 104
c=IN IP4 192.168.1.100
a=rtpmap:111 opus/48000/2
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
m=video 5006 RTP/SAVPF 96 97
a=rtpmap:96 VP8/90000
a=rtpmap:97 H264/90000
Ví dụ trên cho thấy một đoạn SDP điển hình cho phiên WebRTC. Dòng v=0 cho biết phiên bản giao thức. Trường o= chứa định danh của chủ sở hữu phiên và phiên bản. Dòng s=- chỉ định tên phiên (dấu gạch ngang có nghĩa là tên rỗng). Trường t=0 0 cho biết phiên không bị giới hạn thời gian.
Trường a=group:BUNDLE audio video là một thuộc tính nhóm nhiều luồng phương tiện vào một kênh truyền tải duy nhất. Cơ chế BUNDLE cho phép tiết kiệm tài nguyên mạng bằng cách truyền âm thanh và video qua một kết nối duy nhất. Điều này đặc biệt quan trọng đối với các thiết bị di động có băng thông hạn chế.
Đặc tả RFC 8866 định nghĩa một tập hợp các trường bắt buộc và tùy chọn. Các trường bắt buộc bao gồm v= (phiên bản), s= (tên phiên) và t= (thời gian). Trường o= (chủ sở hữu), mặc dù không bắt buộc theo RFC, hầu như luôn có mặt trong các triển khai thực tế.
| Trường | Mục đích | Ví dụ |
|---|---|---|
| v= | Phiên bản giao thức SDP | v=0 |
| o= | Chủ sở hữu và định danh phiên | o=- 46116397 2 IN IP4 192.168.1.100 |
| s= | Tên phiên | s=Video Conference |
| t= | Thời gian bắt đầu và kết thúc phiên | t=0 0 |
| m= | Mô tả luồng phương tiện | m=audio 5004 RTP/SAVPF 111 |
| c= | Thông tin mạng | c=IN IP4 192.168.1.100 |
| a= | Thuộc tính phiên hoặc phương tiện | a=rtpmap:111 opus/48000/2 |
Trường m= (media) là một trong những trường quan trọng nhất. Nó mô tả một luồng phương tiện cụ thể và chứa loại phương tiện (audio, video, text, application), cổng, giao thức truyền tải và danh sách codec được hỗ trợ. Trong WebRTC, các loại phổ biến nhất là audio và video với các giao thức truyền tải RTP/SAVPF (Secure Audio/Video Profile with Feedback) hoặc UDP/TLS/RTP/SAVPF.
Trường a= (attribute) là linh hoạt nhất và có thể mở rộng nhất. Nó có thể chứa rtpmap (ánh xạ số codec với tên), fmtp (tham số codec), fingerprint (dấu vân tay khóa DTLS), ice-ufrag và ice-pwd (thông tin xác thực ICE) và nhiều thuộc tính khác. Thông qua các thuộc tính, SDP hỗ trợ các cơ chế bảo mật hiện đại và NAT traversal.
Trong kiến trúc WebRTC, SDP đóng vai trò là giao thức báo hiệu để mô tả và thương lượng các tham số phiên phương tiện giữa hai bên tham gia. SDP không định nghĩa cơ chế truyền tải các mô tả này — nhiệm vụ này được xử lý bởi kênh báo hiệu, mà nhà phát triển triển khai độc lập qua WebSocket, HTTP hoặc giao thức khác.
Quá trình bắt đầu khi người khởi tạo (caller) tạo một SDP Offer. Để làm điều này, trình duyệt gọi phương thức createOffer() trên đối tượng RTCPeerConnection. Mô tả SDP được tạo chứa tất cả các tham số phiên từ phía người khởi tạo: codec được hỗ trợ, địa chỉ mạng, ứng viên ICE và yêu cầu bảo mật.
const configuration = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };
const pc = new RTCPeerConnection(configuration);
// Thêm các track phương tiện trước createOffer
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
stream.getTracks().forEach(track => pc.addTrack(track, stream));
// Tạo SDP Offer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// Gửi SDP đến peer từ xa qua kênh báo hiệu
sendViaSignaling({ type: 'offer', sdp: offer.sdp });
Sau khi tạo Offer và đặt mô tả cục bộ qua setLocalDescription(), người khởi tạo gửi chuỗi SDP đến người tham gia từ xa qua kênh báo hiệu. Người tham gia từ xa, nhận được SDP Offer, tạo một SDP Answer và gửi lại. Việc trao đổi này được gọi là trao đổi báo hiệu và là bước bắt buộc trước khi thiết lập kết nối peer-to-peer.
Theo đặc tả WebRTC của W3C, trao đổi SDP nên xảy ra trước khi các ứng viên ICE bắt đầu. Trong thực tế, nhiều triển khai gửi ứng viên ICE song song với SDP bằng cơ chế ICE trickle. Điều này giảm thời gian thiết lập kết nối, đặc biệt cho các mạng di động có độ trễ cao.
ICE (Interactive Connectivity Establishment) là một cơ chế sử dụng các thuộc tính SDP để truyền thông tin về các ứng viên mạng. Các ứng viên ICE mô tả các đường dẫn kết nối khả thi: host (địa chỉ cục bộ), srflx (địa chỉ sau NAT, nhận được qua STUN) và relay (địa chỉ máy chủ TURN).
Trong SDP, các ứng viên ICE được truyền qua các thuộc tính a=candidate:, cũng như qua các trường ice-ufrag và ice-pwd để xác thực lưu lượng ICE. Mỗi ứng viên bao gồm giao thức truyền tải (UDP, TCP), địa chỉ IP, cổng và mức ưu tiên. Kết nối thành công được thiết lập qua ứng viên đầu tiên vượt qua kiểm tra kết nối. Cơ chế ICE restart cho phép cập nhật kết nối khi mạng thay đổi.
Đối với các ứng dụng di động, ứng viên ICE đặc biệt quan trọng vì các thiết bị thường ở sau NAT hoặc tường lửa doanh nghiệp. Cơ chế ICE cho phép tìm đường dẫn hoạt động ngay cả trong điều kiện mạng phức tạp, và SDP đóng vai trò là vùng chứa truyền tải cho thông tin này.
SDP trong WebRTC bao gồm các thuộc tính bảo mật cần thiết, đặc biệt là dấu vân tay DTLS và các tham số SRTP. Trường a=fingerprint:sha-256 chứa dấu vân tay của chứng chỉ DTLS, được sử dụng để xác thực và mã hóa luồng phương tiện. Nếu không có thuộc tính này, kết nối WebRTC sẽ không được thiết lập.
Các cơ chế bảo mật bổ sung bao gồm thuộc tính a=setup:, xác định vai trò bắt tay DTLS (active, passive, actpass), và a=ice-lite: để triển khai ICE đơn giản hóa ở phía máy chủ. Tất cả các tham số này được truyền trong SDP và được cả hai bên xác minh trước khi bắt đầu truyền dữ liệu phương tiện.
Trong mô hình WebRTC, có hai loại thông báo SDP: Offer (đề xuất) và Answer (trả lời). Offer được tạo bởi người khởi tạo kết nối và chứa mô tả đầy đủ về phiên phương tiện mong muốn. Answer được tạo bởi người tham gia từ xa để đáp lại Offer và chứa các khả năng của họ có tính đến các ràng buộc do đề xuất đặt ra.
Sự khác biệt chính giữa Offer và Answer nằm ở ngữ nghĩa của các thuộc tính. Offer liệt kê tất cả các codec, giao thức truyền tải và địa chỉ mạng được hỗ trợ mà người khởi tạo có thể đề xuất. Answer chọn một tập hợp con các khả năng này mà phía từ xa hỗ trợ. Ví dụ, nếu Offer đề xuất opus, ISAC và PCMU, Answer có thể chỉ chọn opus là codec ưa thích nhất.
Quá trình trao đổi được điều chỉnh bởi đặc tả WebRTC của W3C và bao gồm một số trạng thái của RTCPeerConnection. Sau khi tạo Offer qua createOffer() và đặt nó làm mô tả cục bộ, kết nối chuyển sang trạng thái have-local-offer. Sau khi nhận Answer và đặt nó làm mô tả từ xa qua setRemoteDescription(), kết nối chuyển sang trạng thái stable — trạng thái cuối cùng sẵn sàng truyền phương tiện.
SDK di động cho WebRTC — Google WebRTC cho Android và WebRTC.framework cho iOS — hỗ trợ đầy đủ trao đổi SDP qua Offer và Answer. Trên Android, lớp PeerConnection với phương thức createOffer() được sử dụng để tạo Offer, tương tự API trình duyệt. Mô tả SDP kết quả được truyền dưới dạng chuỗi qua kênh báo hiệu.
Trên iOS, làm việc với SDP được thực hiện qua lớp RTCSessionDescription từ framework WebRTC. Khi khởi tạo, loại (RTCSdpTypeOffer hoặc RTCSdpTypeAnswer) và chuỗi SDP được chỉ định. Nền tảng tự động phân tích SDP và cấu hình kết nối theo các tham số được truyền.
val configuration = PeerConnection.RTCConfiguration(List())
val peerConnection = factory.createPeerConnection(configuration, object : PeerConnection.Observer {
override fun onIceCandidate(candidate: IceCandidate) { }
})
// Tạo SDP Offer trên Android
peerConnection.createOffer(object : SdpObserver {
override fun onCreateSuccess(sdp: SessionDescription) {
peerConnection.setLocalDescription(this, sdp)
// Gửi chuỗi SDP đến peer từ xa
sendSdpToRemotePeer(sdp.description)
}
}, new MediaConstraints())
Khả năng làm việc trực tiếp với chuỗi SDP mang lại sự linh hoạt cho nhà phát triển: họ có thể sửa đổi SDP trước khi gửi, thêm hoặc xóa codec cụ thể, cấu hình tham số ICE hoặc thêm thuộc tính tùy chỉnh. Đối với ứng dụng Android, thường cần tắt video trong SDP khi băng thông mạng thấp — điều này được thực hiện bằng cách xóa các dòng m= tương ứng khỏi mô tả SDP.
Trong phát triển di động, SDP được sử dụng chủ yếu trong bối cảnh WebRTC — để tạo ứng dụng có cuộc gọi video, trò chuyện thoại và phát trực tiếp. Ứng dụng di động trên Android và iOS có thể hoạt động như cả người khởi tạo và người nhận thông báo SDP, cho phép các kết nối peer-to-peer đối xứng.
Một đặc điểm của ứng dụng di động là cần làm việc với SDP trong điều kiện chất lượng mạng thay đổi. Khi chuyển đổi giữa Wi-Fi và internet di động, cũng như khi băng thông thay đổi, có thể cần tạo mô tả SDP mới. Điều này được thực hiện bằng cơ chế đàm phán lại — trao đổi SDP lặp lại qua createOffer() và setLocalDescription().
Theo nhóm Google WebRTC (2023), tối ưu hóa trao đổi SDP cho thiết bị di động bao gồm sử dụng ICE restart khi thay đổi mạng, ưu tiên codec tốc độ bit thấp (opus cho âm thanh, VP8 cho video) và giảm thiểu kích thước chuỗi SDP bằng cách loại trừ các luồng phương tiện không cần thiết. Lợi thế chính là giảm độ trễ khi thiết lập kết nối trong điều kiện mạng di động.
Một trong những nhiệm vụ chính khi làm việc với SDP trên thiết bị di động là giảm thiểu kích thước mô tả SDP. Một SDP đầy đủ cho phiên WebRTC điển hình với âm thanh và video có thể chiếm 2–5 KB, là đáng kể đối với mạng chậm. Tối ưu hóa bao gồm sử dụng BUNDLE (ghép kênh luồng), loại bỏ codec không được hỗ trợ và nén các ứng viên ICE.
Một vấn đề bổ sung cho thiết bị di động là thời gian sống hạn chế của SDP. Trong điều kiện kết nối không ổn định, SDP có thể trở nên lỗi thời trước khi người tham gia từ xa có thể xử lý nó. Giải pháp là sử dụng thời gian chờ ngắn để nhận Answer và gửi lại SDP nếu cần. Cơ chế ICE restart cho phép cập nhật kết nối mà không cần tạo lại RTCPeerConnection hoàn toàn. Thuộc tính a=ice-lite đơn giản hóa triển khai ICE ở phía máy chủ.
Các nhà phát triển ứng dụng di động có quyền truy cập vào các thư viện có sẵn giúp đơn giản hóa việc làm việc với SDP. libjingle_peerconnection (Google WebRTC) là thư viện chính cho Android, cung cấp API đầy đủ để quản lý SDP. Cho iOS, WebRTC.framework với chức năng tương tự được sử dụng. Cả hai thư viện đều tự động tạo và phân tích SDP, nhưng cung cấp quyền truy cập vào chuỗi SDP thô khi cần.
Để kiểm soát SDP chi tiết hơn, có các giải pháp của bên thứ ba: sdp-transform (JavaScript hoặc Node.js) để phân tích và sửa đổi SDP, NICENICE (Java) để làm việc với ứng viên ICE và SDK có sẵn từ các nhà cung cấp hạ tầng WebRTC xử lý tất cả trao đổi báo hiệu, bao gồm SDP.
Câu hỏi thường gặp
SDP là một định dạng văn bản trong đó những người tham gia phiên mô tả codec, cổng và giao thức họ hỗ trợ. Nó không truyền video hay âm thanh, mà chỉ thương lượng các tham số kết nối. Phép tương tự: SDP là thực đơn, RTP là các món ăn thực tế.
SIP là giao thức điều khiển phiên thiết lập, sửa đổi và kết thúc cuộc gọi. SDP là định dạng mô tả được nhúng trong nội dung thông báo SIP để truyền các tham số phương tiện. SIP trả lời câu hỏi “ai đang gọi và gọi cho ai”, trong khi SDP trả lời “sử dụng codec và cổng nào”.
Có, chuỗi SDP có thể được sửa đổi trước khi thiết lập kết nối. Nhà phát triển thường chỉnh sửa SDP để buộc chọn codec cụ thể, thêm thuộc tính tùy chỉnh hoặc xóa các luồng phương tiện không được hỗ trợ. Tuy nhiên, các thay đổi phải được cả hai bên đồng ý, nếu không kết nối sẽ không được thiết lập.
SDP được truyền qua một kênh báo hiệu riêng biệt mà nhà phát triển triển khai độc lập. Các tùy chọn điển hình bao gồm WebSocket cho ứng dụng web, yêu cầu HTTP POST (REST API) hoặc giao thức gốc cho ứng dụng di động. WebRTC không định nghĩa phương pháp truyền SDP, chỉ định dạng của nó.
BUNDLE là cơ chế SDP kết hợp nhiều luồng phương tiện (âm thanh, video, dữ liệu) vào một kênh truyền tải duy nhất. Thay vì các cổng riêng biệt cho mỗi luồng, một cổng và một kết nối ICE được sử dụng. Điều này giảm tải cho thiết bị di động và giảm độ trễ.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.