Làm thế nào để tài nguyên phát trực tuyến phù hợp với mô hình RESTful?


101

Với dịch vụ RESTful, bạn có thể tạo, đọc, cập nhật và xóa tài nguyên. Tất cả điều này đều hoạt động tốt khi bạn đang xử lý một thứ gì đó như nội dung cơ sở dữ liệu - nhưng điều này chuyển thành dữ liệu truyền trực tuyến như thế nào? (Hoặc có phải không?) Ví dụ, trong trường hợp video, có vẻ ngớ ngẩn khi coi mỗi khung hình là tài nguyên mà tôi nên truy vấn từng khung hình một. Thay vào đó, tôi sẽ thiết lập một kết nối ổ cắm và truyền một loạt các khung hình. Nhưng điều này có phá vỡ mô hình RESTful không? Điều gì sẽ xảy ra nếu tôi muốn có thể tua lại hoặc tua đi luồng phát nhanh? Điều này có khả thi trong mô hình RESTful không? Vậy: Làm thế nào để tài nguyên phát trực tuyến phù hợp với mô hình RESTful?

Về vấn đề triển khai, tôi đã sẵn sàng để tạo một dịch vụ dữ liệu trực tuyến như vậy và tôi muốn đảm bảo rằng tôi đang thực hiện nó theo "cách tốt nhất". Tôi chắc rằng vấn đề này đã được giải quyết trước đây. Ai đó có thể chỉ cho tôi tài liệu tốt không?


2
Cuối cùng bạn đã chọn phương án nào? Bạn đã xem gRPc chưa? Nó hỗ trợ phát trực tuyến hai chiều.
Mac

Câu trả lời:


80

Tôi đã không quản lý để tìm tài liệu về phát trực tuyến RESTful thực sự - có vẻ như kết quả chủ yếu là về việc ủy ​​quyền phát trực tuyến cho một dịch vụ khác (đó không phải là một giải pháp tồi). Vì vậy, tôi sẽ cố gắng hết sức để tự mình giải quyết - lưu ý rằng phát trực tuyến không phải là miền của tôi, nhưng tôi sẽ cố gắng thêm 2 xu của mình.

Ở khía cạnh phát trực tuyến, tôi nghĩ rằng chúng ta cần tách vấn đề thành hai phần độc lập:

  1. truy cập vào tài nguyên phương tiện (dữ liệu meta)
  2. quyền truy cập vào phương tiện / chính luồng (dữ liệu nhị phân)

1.) Quyền truy cập vào tài nguyên phương tiện
Điều này khá đơn giản và có thể được xử lý một cách sạch sẽ và RESTful. Ví dụ: giả sử chúng ta sẽ có một API dựa trên XML cho phép chúng ta truy cập vào danh sách các luồng:

GET /media/

<?xml version="1.0" encoding="UTF-8" ?>
<media-list uri="/media">
    <media uri="/media/1" />
    <media uri="/media/2" />
    ...
</media-list>

... và cả các luồng riêng lẻ:

GET /media/1

<?xml version="1.0" encoding="UTF-8" ?>
<media uri="/media/1">
    <id>1</id>
    <title>Some video</title>
    <stream>rtsp://example.com/media/1.3gp</stream>
</media>

2.) Quyền truy cập vào chính phương tiện / luồng
Đây là bit có vấn đề hơn. Bạn đã chỉ ra một tùy chọn trong câu hỏi của mình và đó là cho phép truy cập vào từng khung thông qua API RESTful. Mặc dù điều này có thể hiệu quả, tôi đồng ý với bạn rằng đó không phải là một lựa chọn khả thi.

Tôi nghĩ rằng có một sự lựa chọn được thực hiện giữa:

  1. ủy quyền phát trực tuyến cho một dịch vụ chuyên dụng thông qua một giao thức phát trực tuyến chuyên biệt (ví dụ: RTSP)
  2. sử dụng các tùy chọn có sẵn trong HTTP

Tôi tin rằng cái trước là sự lựa chọn hiệu quả hơn, mặc dù nó yêu cầu một dịch vụ phát trực tuyến chuyên dụng (và / hoặc phần cứng). Có thể hơi khó hiểu về những gì được coi là RESTful, tuy nhiên lưu ý rằng API của chúng tôi RESTful về mọi mặt và mặc dù dịch vụ phát trực tuyến chuyên dụng không tuân thủ giao diện thống nhất (GET / POST / PUT / DELETE), API của chúng tôi làm. API của chúng tôi cho phép chúng tôi kiểm soát thích hợp các tài nguyên và dữ liệu meta của chúng thông qua GET / POST / PUT / DELETE và chúng tôi cung cấp các liên kết đến dịch vụ phát trực tuyến (do đó tuân theo khía cạnh kết nối của REST).

Tùy chọn thứ hai - phát trực tuyến qua HTTP - có thể không hiệu quả bằng tùy chọn trên, nhưng nó chắc chắn có thể. Về mặt kỹ thuật, nó không khác lắm so với việc cho phép truy cập vào bất kỳ dạng nội dung nhị phân nào thông qua HTTP. Trong trường hợp này, API của chúng tôi sẽ cung cấp một liên kết đến tài nguyên nhị phân có thể truy cập qua HTTP và cũng tư vấn cho chúng tôi về kích thước của tài nguyên:

GET /media/1

<?xml version="1.0" encoding="UTF-8" ?>
<media uri="/media/1">
    <id>1</id>
    <title>Some video</title>
    <bytes>1048576</bytes>
    <stream>/media/1.3gp</stream>
</media>

Máy khách có thể truy cập tài nguyên qua HTTP bằng cách sử dụng GET /media/1.3gp. Một tùy chọn là để khách hàng tải xuống toàn bộ tài nguyên - tải xuống liên tục HTTP . Một giải pháp thay thế rõ ràng hơn là cho máy khách truy cập tài nguyên theo từng phần bằng cách sử dụng tiêu đề Phạm vi HTTP . Để tìm nạp đoạn 256KB thứ hai của tệp có dung lượng lớn 1MB, yêu cầu của khách hàng khi đó sẽ giống như sau:

GET /media/1.3gp
...
Range: bytes=131072-262143
...

Sau đó, một máy chủ hỗ trợ phạm vi sẽ phản hồi với tiêu đề Phạm vi nội dung , theo sau là phần trình bày một phần của tài nguyên:

HTTP/1.1 206 Partial content
...
Content-Range: bytes 131072-262143/1048576
Content-Length: 1048576
...

Lưu ý rằng API của chúng tôi đã cho khách hàng biết kích thước chính xác của tệp tính bằng byte (1MB). Trong trường hợp máy khách không biết kích thước của tài nguyên, trước tiên nó phải gọi HEAD /media/1.3gpđể xác định kích thước, nếu không nó có nguy cơ bị máy chủ phản hồi với 416 Requested Range Not Satisfiable.


2
Wow ... đây là thông tin tuyệt vời. Bạn đã thu hút sự chú ý của tôi đến một số cách mới để nghĩ về điều này. Tôi cũng không biết gì về Giao thức phát trực tuyến thời gian thực.
JnBrymn

1
Không thành vấn đề, tôi rất vui vì tôi có thể giúp được. Tuy nhiên, xin lưu ý rằng tôi chưa có cơ hội làm việc với các giao thức phát trực tuyến một cách cá nhân (ngoại trừ phát trực tuyến liên tục qua HTTP). Tôi đã chọn RTSP chỉ là một ví dụ, tôi không thể biết liệu nó có thể hữu ích trong trường hợp cụ thể của bạn hay không. Bạn có thể muốn hỏi một câu hỏi SO khác về các giao thức phát trực tuyến cụ thể. Wikipedia cũng cung cấp một điểm khởi đầu tốt cho các giao thức khác - xem phần "Các vấn đề về giao thức" và "Xem thêm" tại đây: en.wikipedia.org/wiki/Streaming_Media
MicE

1
Cảm ơn bạn đây là cách giải thích kỹ thuật và đơn giản nhất.
silentsudo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.