का जवाब देने के लिए एक वेबसाईट क्लाइंट का उपयोग करके सिनात्रा, मैं एक सिनात्रा वेब सर्वर लिख रहा हूं जिसे मैं रीस्टफुल करना चाहता हूं, लेकिन बात यह है कि इसे किसी अन्य सर्वर से बातचीत करना है जो विशेष रूप से वेब सॉकेट के माध्यम से संचार करता है। तो, यह तो होना ही चाहिए:http अनुरोध
- एक अनुरोध एक ग्राहक से मेरी सिनात्रा सर्वर में आता है
- मेरे सर्वर विदेशी सर्वर के लिए एक वेब सॉकेट खोलता
- मेरे सर्वर एसिंक्रोनस रूप से विदेशी से संदेश और बातों के लिए इंतजार कर रहा है सर्वर जब तक सॉकेट बंद कर दिया है (यह केवल दो सौ या तो मिलीसेकेंड लेना चाहिए)
- मेरे सर्वर क्लाइंट के लिए एक प्रतिक्रिया वापस भेजता है
मुझे यकीन है यह भी पूरा करने के लिए जटिल नहीं है कर रहा हूँ लेकिन मैं उस पर थोड़ा फंस गया हूँ। असल में, यदि पूरे वेब सॉकेट तर्क को एक ही फ़ंक्शन में लपेटा जा सकता है, तो उस फ़ंक्शन को अवरुद्ध करने के लिए बनाया जा सकता है, और वह वह होगा। लेकिन मुझे नहीं पता कि वेब सॉकेट तर्क को कैसे लपेटें और इसे अवरुद्ध करें। तुम क्या सोचते हो? मुझे जो मिला है उसका सरलीकृत संस्करण नीचे है।
require 'sinatra'
require 'websocket-client-simple'
get '/' do
ws = WebSocket::Client::Simple.connect(' ws://URL... ')
ws.on :message do
puts 'bar'
end
ws.on :close do
# At this point we need to send an HTTP response back to the client. But how?
end
ws.on :open do
ws.send 'foo'
end
end
संपादित
आगे सोचा के बाद, मुझे एहसास हुआ कि एक तरह से यह एक धागा पड़ाव और एक धागा जगाने का उपयोग किया जा सकता है। इस बल्कि विस्तृत लगता है, और मैं कैसे रूबी के साथ सही ढंग से ऐसा करने के लिए यकीन नहीं है, लेकिन यह विचार है:
require 'sinatra'
require 'websocket-client-simple'
get '/' do
socketResponse('wss:// ... URL ...')
'Got a response from the web socket server!'
end
def socketResponse(url)
thread = Thread.new do
ws = WebSocket::Client::Simple.connect(url)
ws.on :message do
puts 'bar'
# Maybe store each response in a thread-safe array to retrieve later or something
end
ws.on :close do
thread.run
end
ws.on :open do
ws.send 'foo'
end
Thread.stop
end
end
संपादित 2
मैं आगे प्रगति की है। अब मैं Async Sinatra मणि का उपयोग कर रहा हूं, जिसके लिए वेब सर्वर की आवश्यकता है। इस प्रकार यह स्थापित किया गया है:
require 'sinatra'
require 'sinatra/async'
require 'websocket-client-simple'
set :server, 'thin'
register Sinatra::Async
aget '/' do
puts 'Request received'
socketResponse('wss:// ... URL ...')
end
def socketResponse(url)
ws = WebSocket::Client::Simple.connect(url)
puts 'Connected to web socket'
ws.on :message do |message|
puts 'Got message:' + message.to_s
end
ws.on :close do
puts 'WS closed'
body 'Closed ...'
end
ws.on :open do
puts 'WS open'
message = 'A nice message to process'
ws.send message
puts 'Sent: ' + message
end
end
बात यह है कि यह अभी भी काम नहीं कर रहा है। इसके कंसोल आउटपुट की अपेक्षा की जाती है:
Request received
Connected to web socket
WS open
Sent: A nice message to process
Got message: blah blah blah
WS closed
लेकिन यह किसी भी डेटा को क्लाइंट को वापस नहीं भेज रहा है। body 'Closed ...'
विधि का कोई प्रभाव नहीं प्रतीत होता है।
सिडेनोटे: आपके प्रश्न में सुझाए गए डिज़ाइन प्रति-उत्पादक और प्रदर्शन भारी हैं। जब तक आपका एप्लिकेशन चल रहा है, तब तक वेबस्केट कनेक्शन को खुले रखने में अधिक समझदारी होती है। यह वेबसाइकिलों का पूरा बिंदु है - लगातार कनेक्शन बनाए रखना। – Myst
यह मेरा असली कोड नहीं है, लेकिन इसे लिखने का सबसे आसान तरीका है कि मैं समस्या का प्रदर्शन करने के बारे में सोच सकता हूं। लेकिन धन्यवाद, यह एक अच्छी टिप है। – tschwab
बस स्पष्ट करने के लिए, आप वेब सॉकेट कोड चलाने के बाद पृष्ठ लोड नहीं करना चाहते हैं? आप यह भी कहते हैं कि यह async होना चाहिए, इसलिए मैं उलझन में हूँ। आपके पास रूट के अंदर एसिंक फ़ंक्शन हो सकता है, क्योंकि मार्ग एसिंक विधि से किसी भी जानकारी के बिना वापस आ जाएगा। – Cereal