स्ट्रीमिंग संसाधन Restful प्रतिमान के भीतर कैसे फिट होते हैं?


101

RESTful सेवा से आप संसाधन बना सकते हैं, पढ़ सकते हैं, अपडेट कर सकते हैं और हटा सकते हैं। जब आप डेटाबेस एसेट्स जैसी किसी चीज़ के साथ काम कर रहे होते हैं, तो यह सब अच्छा काम करता है - लेकिन यह डेटा स्ट्रीमिंग कैसे करता है? (या करता है?) उदाहरण के लिए, वीडियो के मामले में, प्रत्येक फ्रेम को संसाधन के रूप में मानना ​​मूर्खतापूर्ण लगता है कि मुझे एक बार में एक प्रश्न करना चाहिए। बल्कि मैं एक सॉकेट कनेक्शन स्थापित करूंगा और फ्रेम की एक श्रृंखला को स्ट्रीम करूंगा। लेकिन क्या इससे रेस्टफुल प्रतिमान टूट जाता है? क्या होगा यदि मैं धारा को आगे बढ़ाने या तेजी से आगे बढ़ने में सक्षम होना चाहता हूं? क्या यह संभव प्रतिमान के भीतर संभव है? तो: कैसे स्ट्रीमिंग संसाधनों के भीतर प्रतिमान फिट?

कार्यान्वयन के परिणामस्वरूप, मैं ऐसी स्ट्रीमिंग डेटा सेवा बनाने के लिए तैयार हो रहा हूं, और मैं यह सुनिश्चित करना चाहता हूं कि मैं इसे "सबसे अच्छा तरीका" कर रहा हूं। मुझे यकीन है कि यह समस्या पहले हल हो गई है। क्या कोई मुझे अच्छी सामग्री की ओर इशारा कर सकता है?


2
आपने आखिर कौन सा विकल्प चुना? क्या आपने gRPc को देखा है? यह द्विदिश स्ट्रीमिंग का समर्थन करता है।
मैक

जवाबों:


80

मैंने वास्तव में Restful स्ट्रीमिंग के बारे में सामग्री खोजने का प्रबंधन नहीं किया - ऐसा लगता है कि परिणाम ज्यादातर स्ट्रीमिंग को किसी अन्य सेवा (जो एक बुरा समाधान नहीं है) को सौंपने के बारे में हैं। तो मैं इसे खुद से निपटने की पूरी कोशिश करूंगा - ध्यान दें कि स्ट्रीमिंग मेरा डोमेन नहीं है, लेकिन मैं अपने 2 सेंट जोड़ने की कोशिश करूंगा।

स्ट्रीमिंग के पहलू में, मुझे लगता है कि हमें समस्या को दो स्वतंत्र भागों में अलग करने की आवश्यकता है:

  1. मीडिया संसाधनों तक पहुंच (मेटा डेटा)
  2. माध्यम / स्ट्रीम तक पहुंच (बाइनरी डेटा)

1.) मीडिया संसाधनों तक पहुंच
यह बहुत सरल है और इसे एक स्वच्छ और उत्साहपूर्ण तरीके से नियंत्रित किया जा सकता है। एक उदाहरण के रूप में, मान लें कि हमारे पास XML- आधारित API होगा जो हमें स्ट्रीम की सूची तक पहुँचने की अनुमति देता है:

GET /media/

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

... और व्यक्तिगत धाराओं के लिए भी:

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.) मध्यम / धारा तक पहुंच
यह स्वयं अधिक समस्याग्रस्त बिट है। आपने अपने प्रश्न में पहले से ही एक विकल्प बताया है, और यह है कि Restful API के माध्यम से व्यक्तिगत रूप से फ़्रेम तक पहुंच की अनुमति देना। हालांकि यह काम कर सकता है, मैं आपसे सहमत हूं कि यह एक व्यवहार्य विकल्प नहीं है।

मुझे लगता है कि इसके बीच एक विकल्प है:

  1. एक विशेष स्ट्रीमिंग प्रोटोकॉल (जैसे RTSP) के माध्यम से एक समर्पित सेवा के लिए स्ट्रीमिंग का प्रतिनिधित्व करना
  2. HTTP में उपलब्ध विकल्पों का उपयोग करना

मेरा मानना ​​है कि पूर्व को अधिक कुशल विकल्प माना जाता है, हालांकि इसके लिए एक समर्पित स्ट्रीमिंग सेवा (और / या हार्डवेयर) की आवश्यकता होती है। यह Restful माना जाता है के किनारे पर थोड़ा सा हो सकता है, हालांकि ध्यान दें कि हमारा API सभी पहलुओं में RESTful है और भले ही समर्पित स्ट्रीमिंग सेवा एक समान इंटरफ़ेस (GET / POST / PUT / DELETE) का पालन नहीं करती है, हमारा API कर देता है। हमारा एपीआई हमें GET / POST / PUT / DELETE के माध्यम से संसाधनों और उनके मेटा डेटा पर उचित नियंत्रण की अनुमति देता है, और हम स्ट्रीमिंग सेवा (इस प्रकार REST के कनेक्टिविटी पहलू के साथ पालन) के लिए लिंक प्रदान करते हैं।

बाद वाला विकल्प - HTTP के माध्यम से स्ट्रीमिंग - ऊपर के रूप में कुशल नहीं हो सकता है, लेकिन यह निश्चित रूप से संभव है। तकनीकी रूप से, यह HTTP के माध्यम से द्विआधारी सामग्री के किसी भी रूप तक पहुंच की अनुमति देने से अलग नहीं है। इस स्थिति में हमारा एपीआई HTTP के माध्यम से सुलभ बाइनरी संसाधन का लिंक प्रदान करेगा, और हमें संसाधन के आकार के बारे में भी सलाह देता है:

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>

क्लाइंट HTTP का उपयोग करके संसाधन तक पहुंच सकता है GET /media/1.3gp। एक विकल्प क्लाइंट के लिए संपूर्ण संसाधन डाउनलोड करने के लिए है - HTTP प्रगतिशील डाउनलोड । क्लाइंट के लिए HTTP रेंज हेडर का उपयोग करके क्लीनर में संसाधन का उपयोग करने के लिए एक क्लीनर विकल्प होगा । किसी फ़ाइल का दूसरा 256KB हिस्सा जो 1MB बड़ा है, को लाने के लिए, क्लाइंट अनुरोध फिर इस तरह दिखेगा:

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

एक सर्वर जो पर्वतमाला का समर्थन करता है, तब सामग्री-रेंज हेडर के साथ प्रतिक्रिया करेगा , इसके बाद संसाधन का आंशिक प्रतिनिधित्व होगा:

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

ध्यान दें कि हमारे एपीआई ने ग्राहक को पहले ही बाइट्स (1 एमबी) में फ़ाइल का सटीक आकार बता दिया था। ऐसे मामले में जहां ग्राहक को संसाधन के आकार का पता नहीं होगा, आकार HEAD /media/1.3gpको निर्धारित करने के लिए पहले इसे कॉल करना चाहिए , अन्यथा इसके साथ एक सर्वर प्रतिक्रिया का जोखिम है 416 Requested Range Not Satisfiable


2
वाह ... यह बहुत अच्छी जानकारी है। आपने इस बारे में सोचने के लिए कुछ नए तरीकों से मेरा ध्यान आकर्षित किया है। मैं रियल टाइम स्ट्रीमिंग प्रोटोकॉल से भी अनजान था।
JnBrymn

1
कोई समस्या नहीं है, मुझे खुशी है कि मैं मदद कर सका। कृपया ध्यान दें कि मुझे व्यक्तिगत रूप से अभी तक स्ट्रीमिंग प्रोटोकॉल के साथ काम करने का मौका नहीं मिला है (HTTP के माध्यम से प्रगतिशील स्ट्रीमिंग के अपवाद के साथ)। मैंने आरटीएसपी को केवल एक उदाहरण के रूप में चुना, मैं नहीं बता सकता कि क्या यह आपके विशिष्ट परिदृश्य में उपयोगी हो सकता है। आप विशेष रूप से स्ट्रीमिंग प्रोटोकॉल के बारे में एक और SO प्रश्न पूछना चाहते हैं। विकिपीडिया अन्य प्रोटोकॉल के लिए एक अच्छा प्रारंभिक बिंदु भी प्रस्तुत करता है - "प्रोटोकॉल मुद्दे" और "यहां भी देखें" अनुभाग देखें: en.wikipedia.org/wiki/Streaming_Media
21

1
धन्यवाद, यह अब तक की सबसे सरल और तकनीकी व्याख्या है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.