简体   繁体   English

如何从sinatra应用程序中的类将数据传递到websocket机架?

[英]How can I pass data to websocket-rack from a class in my sinatra app?

I've got a working configuration of websocket-rack in a sinatra app that is intended for a physical installation with multiple screens. 我在sinatra应用程序中有一个websocket-rack的工作配置,该应用程序用于具有多个屏幕的物理安装。 There is functionality working where messages are getting passed back and forth through the websockets just fine. 有一些功能可以正常工作,通过网络套接字来回传递消息。

My problem is this: I have one page with a standard web form (ie not a websocket form), and my goal is to collect the params from that form, turn the params into a string variable, then send the contents of that variable (a string) to a different page/screen through a websocket. 我的问题是:我有一个带有标准Web表单(即不是Websocket表单)的页面,我的目标是从该表单收集参数,将这些参数转换为字符串变量,然后发送该变量的内容(字符串)通过网络套接字转到其他页面/屏幕。 For the life of me, I can't figure out how to do what should be a relatively simple task, because from the main class in my app, I can't communicate with my Socket class, which from what i understand is basically a rack app. 对于我的一生,我无法弄清楚该怎么做应该是一个相对简单的任务,因为从应用程序的主类中,我无法与Socket类进行通信,据我所知,这基本上是一个机架式应用程序。

I tried to resolve it by setting up resque as a middle-man, but quickly discovered that my problem hadn't changed. 我试图通过将resque设置为中间人来解决该问题,但是很快发现我的问题没有改变。 I can't figure out how to call a method and/or pass a variable to the Socket from another class so that it will push to the browser. 我不知道如何调用方法和/或将变量从另一个类传递给Socket,以便它将其推送到浏览器。

Basically, I have an app.rb that is like this: 基本上,我有一个app.rb像这样:

    module SomeThing
      class App < Sinatra::Base
        get '/' do
          #show a form
        end

        post '/submit' do
          #receive params
          #save params
          new_message = params.inspect
          #dream up some way to pass new_message to websocket
        end

        post '/otherscreen' do
          #have an open websocket to receive new_message
        end
      end


      class Socket < Rack::WebSocket::Application

        def on_open(env)
          puts "Client connected"
          send_data "Oh hai!"
        end

        def on_close(env)
          puts "Client disconnected"
        end

        def on_message(env, msg)
           puts "Received message from client: " + msg
        end

        def on_error(env, error)
          puts "An error occured: " + error.message
        end

        def pass_message(env, new_message)
          send_data new_message
        end
      end   
    end

Please let me know if you need more info to solve this. 如果您需要更多信息来解决此问题,请告诉我。 I'm happy to provide whatever is needed, just unsure what that might be right now. 我很乐意提供所需的一切,只是不确定现在可能是什么。

Do you know how I can resolve this? 你知道我该怎么解决吗? It's killing me. 这太痛苦了。

Thanks ahead of time! 提前谢谢!

So, I wrote to the author of websocket-rack, Bernard Potocki, and he said this: 因此,我写信给websocket机架的作者Bernard Potocki,他说:

"What I usually do is save list of active connections to some kind of class variable. One of possible implementations might look like in this gist: https://gist.github.com/imanel/a00d6b65561ebba43b9a " “我通常要做的是保存到某种类变量的活动连接列表。一种可能的实现可能类似于以下要点: https : //gist.github.com/imanel/a00d6b65561ebba43b9a

Contents of gist, in case it gets removed: 要点的内容,以防万一它被删除:

class Socket < Rack::WebSocket::Application

  def self.connections
    @connections ||= []
  end

  def self.send_to_all(message)
    @connections.each {|connection| connection.send_data(message)
  end

  def on_open(env)
    self.class.connections << self
  end

  def on_close(env)
    self.class.connection.delete(self)
  end

end

Ultimately, however, I did not test this solution as we were able to resolve this issue using Redis and Event Machine, so be aware that that is an option as well. 但是最终,我没有测试此解决方案,因为我们能够使用Redis和Event Machine解决此问题,因此请注意,这也是一个选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM