tsc*_*wab 9 rest asynchronous thin sinatra websocket
我正在编写一个我想成为RESTful的Sinatra Web服务器,但问题是它必须与另一个通过Web套接字进行通信的服务器进行交互.所以,这需要发生:
我确信这不是太复杂,但我有点卡在上面.基本上,如果整个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
Run Code Online (Sandbox Code Playgroud)
编辑
经过深思熟虑后,我意识到这可以通过线程停止和线程唤醒来实现.这感觉相当复杂,我不知道如何正确地使用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
Run Code Online (Sandbox Code Playgroud)
编辑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
Run Code Online (Sandbox Code Playgroud)
问题是,它仍然无法正常工作.它的控制台输出如预期:
Request received
Connected to web socket
WS open
Sent: A nice message to process
Got message: blah blah blah
WS closed
Run Code Online (Sandbox Code Playgroud)
但它不会将任何数据发送回客户端.该body 'Closed ...'方法似乎没有任何影响.
问题在于它async-sinatra正在使用自己的线程,因此websocket-client-simple. 解决方案是使用绑定和eval函数,尽管这根本不是很有效。我希望有优化或更好的解决方案可用。
require 'sinatra'
require 'sinatra/async'
require 'websocket-client-simple'
set :server, 'thin'
register Sinatra::Async
aget '/' do
    puts 'Request received'
    socketResponse('wss:// ... URL ...', binding)
end
def socketResponse(url, b)
    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'
        EM.schedule { b.eval " body 'Closed' " }
    end
    ws.on :open do
        puts 'WS open'
        message = 'A nice message to process'
        ws.send message
        puts 'Sent: ' + message
    end
end
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           458 次  |  
        
|   最近记录:  |