我一直在使用一个Web应用程序,它本质上是一个使用sinatra的网络信使。我的目标是使用pgp加密所有消息,并使用faye websocket在客户端之间进行全双工通信。
我的主要问题是能够使用faye向特定客户端发送消息。为了增加这一点,我在单个聊天室中的所有消息都会为每个人保存两次,因为它是pgp加密的。
到目前为止,我已经想过为每个客户端启动一个新的套接字对象并将它们存储在一个哈希中。我不知道这种方法是否是最有效的方法。我已经看到socket.io例如允许你发射到特定的客户端,但似乎没有使用faye websockets?我也在考虑使用pub子模型,但我再次不确定。
感谢任何建议!
答案 0 :(得分:1)
我是iodine's作者,所以我的方法可能会有偏见。
我会考虑根据使用的ID命名频道(即user1
... user201983
并将讯息发送到用户的频道。
我认为Faye会支持这一点。我知道当使用碘原生腹板和内置的pub / sub时,这非常有效。
到目前为止,我已经想过为每个客户端启动一个新的套接字对象并将它们存储在一个哈希...
这是一个非常常见的错误,通常可以在简单的例子中看到。
它仅适用于单个进程环境,而且您必须重新编码整个逻辑才能扩展应用程序。
通道方法允许您使用Redis或任何其他发布/订阅服务进行扩展,而无需重新编码应用程序的逻辑。
这是一个可以从Ruby终端(irb
)运行的快速示例。我只是使用plezi.io来缩短代码:
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!")