gpt4 book ai didi

rest - Sinatra 使用 websocket 客户端响应 http 请求

转载 作者:行者123 更新时间:2023-12-04 04:37:00 25 4
gpt4 key购买 nike

我正在编写一个我想成为 RESTful 的 Sinatra Web 服务器,但问题是它必须与另一个通过 Web 套接字进行通信的服务器交互。所以,这需要发生:

  • 来自客户端
  • 的请求进入我的 Sinatra 服务器
  • 我的服务器打开一个到外部服务器的 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

    编辑 2

    我取得了进一步的进展。我现在使用 Async Sinatra gem ,需要 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 ...'方法似乎没有任何效果。

    最佳答案

    问题是 async-sinatra正在使用它自己的线程,websocket-client-simple 也是如此.解决方案是使用绑定(bind)和 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

    关于rest - Sinatra 使用 websocket 客户端响应 http 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45987788/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com