我正在編寫一個Sinatra Web服務器,我想成爲RESTful,但事情是它必須與另一臺通過Web套接字進行通信的服務器進行交互。所以,這需要發生:Sinatra使用WebSocket客戶端來響應http請求
- 一個請求進入我的末日服務器從客戶
- 我的服務器打開一個網絡套接字連接到國外服務器
- 我的服務器異步等待來自國外的消息,事情服務器,直到關閉套接字(這應該只需要兩百元左右毫秒)
- 我的服務器返回給客戶端的響應
我敢肯定,這是不是太複雜的實現,但我有點卡住了。基本上,如果整個web套接字邏輯可以封裝在一個函數中,那麼這個函數可能會被封鎖,那就是這樣。但我不知道如何封裝web套接字邏輯並阻止它。你怎麼看?下面是我得到的簡化版本。
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
編輯
進一步的思考後,我意識到,一種方式,這可能會使用一個線程停止和線程喚醒來完成。這種感覺相當精巧,我不知道如何使用Ruby正確地做到這一點,但這是想法:
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
EDIT 2
我已經取得了進一步進展。我現在使用的是Async Sinatra寶石,它需要Thin網絡服務器。這是它如何設置:
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 ...'
似乎沒有任何效果。
旁註:在您的問題建議的設計是適得其反,性能沉重。只要應用程序運行,保持WebSocket連接始終處於打開狀態更有意義。這就是websockets的重點 - 維持持續的連接。 – Myst
這不是我真正的代碼,而只是寫出來的最簡單的方式,我可以想象它來演示問題。但是,謝謝你,這是一個很好的提示。 – tschwab
只是爲了澄清,你不希望網頁加載後,直到網絡套接字代碼運行?你也說它應該是異步的,所以我很困惑。您可以在路由中使用異步函數,因爲路由將返回而不包含異步方法的任何信息。 – Cereal