Sinatra:事件分发

时间:2014-06-23 12:47:40

标签: ruby sinatra event-stream

我正在开发一款小应用。发送任务后,用户可以收到一系列状态消息 - 以这种方式可以了解性能是否成功。这可以通过SSE和JS事件订阅来实现。问题是事件分布和变量隔离 - 我从未使用过多租户。

每个用户都应该使用自己的应用实例。每个用户都应该收到自己的活动。

我知道如何实现身份验证机制以及如何为每个任务提供唯一ID,但如何在Sinatra应用程序中实现多租户?有许多宝石和食谱,但所有这些都是为RoR编写的。

我的应用提供了Asterisk传真处理功能。它由两部分组成:第一部分是Sinatra的路由处理程序,第二部分是后端进程 - 它监听Asterisk事件(AMI),还提供新的任务发送。

正如大家所说仍然很难理解我的应用程序应该做什么,我将逐步描述它。

  1. 用户登录。
  2. 用户发送电话任务(例如传真)。它必须是异步过程,因为你永远不会知道会发生什么:可能会很忙,答案可能会在第5天,第9秒......等等。
  3. 因此,在此过程中,用户会收到描述正在发生的事情的消息(我们的后台进程与电话服务器进行通信)。
  4. 但此时此时,另一位用户用户正在登录并发送自己的任务。两个用户都会看到他们的私人活动流程。
  5. 但这不会发生:用户会看到2个事件流的混乱。这是我的问题。

    实际上我的任务与聊天室实施类似,不同之处在于人们不应该互相交谈。他们应该通过服务器与后台进程“交谈”。每个人都可以说“Hello”,服务器将“Hello”重定向到后台进程,然后从后台进程返回给所有者的私有答案流,这是异步发生的。在聊天室,你可以对另一个伙伴说“你好”,你永远不知道你什么时候会收到答案,但服务器知道这个答案是你的 - 你会得到你的私人答案。

    以下是片段:

    class FaxServer < Sinatra::Base
     ...
     post '/run' do
      settings.backend_process.async.run(param1, param2)
     end
     ...
    end
    
    class MyBackendProcess
     def run(number, file)
      if File.exist?(file) then
       change_status("Calling attempt, please wait...")
       $stream.async.send_action ...
     end
     ...
     def handle_event(event)
      case
      when event.name === "Newchannel"
      change_status("New channel is created")
      ...
     end
    end
    
    class StatusSender
     include Celluloid
     include Celluloid::Notifications
    
     def send_status(message)
      publish("status_event", "#{Time.now.strftime('%R:%S')} : #{message}")
     end
    end
    
    class StatusObserver
      include Celluloid
      include Celluloid::Notifications
    
      def initialize(server)
        @server = server
        subscribe "status_event", :status_event 
      end
    
      def status_event(*args)
        @server.settings.connections.each { |out| out << "event: #{args[0].to_s}\ndata: #{args[1]}\n\n" }
      end
    end
    

    提前致谢。

0 个答案:

没有答案