私はRESTfulになりたいSinatra Webサーバーを作成していますが、それはWebソケット経由で通信する別のサーバーと対話しなければならないことです。だから、これは起こる必要があります:SinatraがHTTPリクエストに応答するためにwebsocketクライアントを使用
- 要求が私のサーバが外部サーバへのWebソケットを開き
- クライアントからの私のシナトラサーバーに入ってくる 私のサーバが非同期的に外国からのメッセージや物事を待ち
- ソケットが閉じられるまで、サーバーが
- 私のサーバがクライアントに応答を返す(これが唯一の200かそこらミリ秒を取る必要があります)
私は、これは達成するにはあまりにも複雑ではありません確信しているが、私はちょっとそれに固執しています。基本的には、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
EDIT
さらに考えた後、私は、これはスレッド停止とスレッドウェイクアップを使用して行われるかもしれないというやり方ことに気づきました。これはかなり精巧な感じ、と私は、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 gemを使用しています。これにはThin Webサーバーが必要です。これは設定方法です:
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接続を開いたままにしておく方が理にかなっています。それがウェブソケットの全ポイントです。永続的な接続を維持しています。 – Myst
これは私の実際のコードではありませんが、問題を示すために考えることができる最も簡単な方法を書いています。しかし、ありがとう、それは良いヒントです。 – tschwab
明確にするために、ウェブソケットコードが実行されるまでページを読み込まないようにしますか?あなたはそれが非同期であるべきであると述べているので、私は混乱しています。非同期メソッドからの情報なしでルートが返るため、ルート内に非同期関数を持たせることができます。 – Cereal