Ruby 如何使用Faye Websockets向特定客户端发送消息?

Ruby 如何使用Faye Websockets向特定客户端发送消息?,ruby,web-applications,websocket,sinatra,faye,Ruby,Web Applications,Websocket,Sinatra,Faye,我一直在开发一个web应用程序,它本质上是一个使用sinatra的web messenger。我的目标是使用pgp对所有消息进行加密,并使用faye websocket在客户端之间进行全双工通信 我的主要问题是能够使用faye向特定的客户端发送消息。此外,我在一个聊天室中的所有信息都会为每个人保存两次,因为它是pgp加密的 到目前为止,我考虑为每个客户机启动一个新的套接字对象,并将它们存储在散列中。我不知道这种方法是否最有效。例如,我已经看到socket.io允许您向特定客户机发送消息,但似乎不

我一直在开发一个web应用程序,它本质上是一个使用sinatra的web messenger。我的目标是使用pgp对所有消息进行加密,并使用faye websocket在客户端之间进行全双工通信

我的主要问题是能够使用faye向特定的客户端发送消息。此外,我在一个聊天室中的所有信息都会为每个人保存两次,因为它是pgp加密的

到目前为止,我考虑为每个客户机启动一个新的套接字对象,并将它们存储在散列中。我不知道这种方法是否最有效。例如,我已经看到socket.io允许您向特定客户机发送消息,但似乎不允许使用faye websockets?我也在考虑可能使用酒吧子模型,但我再一次不确定

任何建议都将不胜感激,谢谢

我是作者,所以我的方法可能有偏见

我会考虑用已使用的ID来命名一个频道(即<代码> USE1 …>代码> USE201983 1983 /代码>,并将消息发送到用户的频道。

我认为Faye会支持这一点。我知道当使用Idio原生WebSocket和内置酒吧/酒吧时,这是非常有效的

到目前为止,我一直在考虑为每个客户机启动一个新的套接字对象,并将它们存储在散列中

这是一个非常常见的错误,常见于简单的例子中

它只在单进程环境中工作,因此为了扩展应用程序,您必须重新编码整个逻辑

通道方法允许您使用Redis或任何其他发布/订阅服务进行扩展,而无需重新编码应用程序的逻辑

下面是一个可以从Ruby终端(
irb
)运行的快速示例。我使用它只是为了将代码缩短一点:

require 'plezi'

class Example
  def index
    "Use Websockets to connect."
  end
  def pre_connect
    if(!params[:id])
      puts "an attempt to connect without credentials was made."
      return false
    end
    return true
  end
  def on_open
    subscribe channel: params[:id]
  end
  def on_message data
    begin
      msg = JSON.parse(data)
      if(!msg["to"] || !msg["data"])
        puts "JSON message error", data
        return
      end
      msg["from"] = params[:id]
      publish channel: msg["to"].to_s, message: msg.to_json
    rescue => e
      puts "JSON parsing failed!", e.message
    end

  end
end

Plezi.route "/" ,Example
Iodine.threads = 1
exit
要测试此示例,请使用Javascript客户端,可能类似于以下内容:

// in browser tab 1
var id = 1
ws = new WebSocket("ws://localhost:3000/" + id)
ws.onopen = function(e) {console.log("opened connection");}
ws.onclose = function(e) {console.log("closed connection");}
ws.onmessage = function(e) {console.log(e.data);}
ws.send_to = function(to, data) {
    this.send(JSON.stringify({to: to, data: data}));
}.bind(ws);

// in browser tab 2
var id = 2
ws = new WebSocket("ws://localhost:3000/" + id)
ws.onopen = function(e) {console.log("opened connection");}
ws.onclose = function(e) {console.log("closed connection");}
ws.onmessage = function(e) {console.log(e.data);}
ws.send_to = function(to, data) {
    this.send(JSON.stringify({to: to, data: data}));
}.bind(ws);

ws.send_to(1, "hello!")

我是《代码>碘<代码>作者,所以我可能有偏见,但我会考虑用已使用的ID来命名频道。(即,
user1
user201983
并将消息发送到用户频道。当使用Iodium native WebSocket和内置酒吧/酒吧时,这非常有效。哇,非常感谢,在我尝试之前我从未听说过plezi.io。非常感谢!@Michelchatmijian,欢迎你。如果我的回答有帮助,请投一票我相信你可以用Sinatra和Faye做同样的事情,同样的概念应该适用(尽管可能需要更多的代码)。