0

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

每个用户都应该使用自己的应用程序实例。每个用户都应该收到自己的事件。

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

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

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

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

但这不会发生:用户看到 2 个事件流的混乱。那是我的问题。

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

以下是片段:

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

提前致谢。

4

0 回答 0