如何将数据从 sinatra 应用程序中的类传递到 websocket-rack? [英] How can I pass data to websocket-rack from a class in my sinatra app?

查看:46
本文介绍了如何将数据从 sinatra 应用程序中的类传递到 websocket-rack?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 sinatra 应用程序中有一个 websocket-rack 的工作配置,该应用程序旨在用于具有多个屏幕的物理安装.有一些功能可以让消息通过 websocket 来回传递就好了.

I've got a working configuration of websocket-rack in a sinatra app that is intended for a physical installation with multiple screens. There is functionality working where messages are getting passed back and forth through the websockets just fine.

我的问题是:我有一个带有标准 Web 表单(即不是 websocket 表单)的页面,我的目标是从该表单中收集参数,将这些参数转换为字符串变量,然后发送该变量(一个字符串)通过 websocket 到不同的页面/屏幕.对于我的生活,我无法弄清楚如何做应该是相对简单的任务,因为从我的应用程序中的主类来看,我无法与我的 Socket 类进行通信,据我了解,这基本上是一个机架应用.

My problem is this: I have one page with a standard web form (i.e. 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. 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.

我试图通过将 resque 设置为中间人来解决它,但很快发现我的问题并没有改变.我不知道如何从另一个类调用方法和/或将变量传递给 Socket,以便它推送到浏览器.

I tried to resolve it by setting up resque as a middle-man, but quickly discovered that my problem hadn't changed. 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.

基本上,我有一个像这样的 app.rb:

Basically, I have an app.rb that is like this:

    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.

提前致谢!

推荐答案

于是,我写信给 websocket-rack 的作者 Bernard Potocki,他是这样说的:

So, I wrote to the author of websocket-rack, Bernard Potocki, and he said this:

我通常做的是将活动连接列表保存到某种类变量.其中一种可能的实现可能如下所示:https://gist.github.com/imanel/a00d6b65561ebba43b9a "

"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 "

要点的内容,以防它被删除:

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

不过,最终我没有测试这个解决方案,因为我们能够使用 Redis 和 Event Machine 解决这个问题,所以请注意这也是一个选项.

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.

这篇关于如何将数据从 sinatra 应用程序中的类传递到 websocket-rack?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆