gpt4 book ai didi

ruby - Faye ruby​​ 客户端只发布一次

转载 作者:数据小太阳 更新时间:2023-10-29 07:30:09 25 4
gpt4 key购买 nike

我有一个在本地主机上运行的 faye 服务器 (nodejs),我正在尝试设置一个需要定期在服务器上发布的服务器端 ruby​​ 客户端。这是我正在尝试使用的代码。(请忽略开头的注释代码)。
我创建了一个类变量 @@client 并在类加载后立即对其进行初始化。我定义了一个类方法pub,它的任务是在faye服务器上发布一些东西。
最后,我只是调用了两次 pub 方法。成功接收到第一个发布回调,但第二个发布没有进行 callbackerrback。由于控制权尚未交还给应用程序,应用程序就卡在那里。
如果我创建 gobal 变量 $client(当前已注释),行为是相同的。但是,如果我每次调用 pub 时都创建客户端,那么发布就会顺利进行。我在 EM.run 循环或外部启动它,行为是相同的。 (如预期的那样)

我不想在每次发布内容时都建立一个新的连接,因为这违背了目的。此外,如果我每次调用该方法时都在 EM.run 中创建一个新客户端,则客户端连接不会自行关闭。我可以看到它们在 lsof 命令中作为打开的文件打开,我想很快我就会开始收到 too many open files 错误。

我不太正确地理解 Event Machine,也许我在那里遗漏了一些东西。

require 'faye'
require 'eventmachine'

# $client = Faye::Client.new('http://localhost:5050/faye')
class Fayeclient
puts "#{__LINE__}: Reactor running: " + EM.reactor_running?.to_s

# if !defined? @@client or @@client.nil?
@@client = Faye::Client.new('http://localhost:5050/faye')
puts "Created client: " + @@client.inspect
# end

def self.pub
puts "#{__LINE__}: Reactor running: " + EM.reactor_running?.to_s
# client = Faye::Client.new('http://localhost:5050/faye') #$client
# client = @@client
EM.run {
#client = Faye::Client.new('http://localhost:5050/faye') #$client
puts "#{__LINE__}: Reactor running: " + EM.reactor_running?.to_s
puts @@client.inspect

publication = @@client.publish('/foo', 'text' =>'Hello world')
puts "Publishing: #{publication.inspect}"
# puts "Publication methods: #{publication.methods}"

publication.callback do
puts "Did it #{publication.inspect}"
EM.stop_event_loop
puts "#{__LINE__}: Reactor running: " + EM.reactor_running?.to_s
# puts "#{client.methods}"
# puts client.inspect
# client.remove_all_listeners
# puts client.inspect
end
publication.errback do |error |
puts error.inspect
EM.stop_event_loop
end
}
puts "Outside event loop"
puts "#{__LINE__}: Reactor running: " + EM.reactor_running?.to_s
end
end

Fayeclient.pub
Fayeclient.pub

最佳答案

EM.run 调用是阻塞的,您必须在单独的线程上运行它,并在一切结束时最终加入它。在我使用的示例中 Singleton但这取决于你。

这会正确执行 2 个 faye 调用。

#!/usr/bin/env ruby
#
require 'faye'
require 'singleton'
require 'eventmachine'


class Fayeclient
include Singleton
attr_accessor :em_thread, :client

def initialize
self.em_thread = Thread.new do
EM.run
end
self.client = Faye::Client.new('http://localhost:8890/faye')
end

def pub
puts "#{__LINE__}: Reactor running: " + EM.reactor_running?.to_s
puts client.inspect

publication = client.publish('/foo', 'text' =>'Hello world')
puts "Publishing: #{publication.inspect}"

publication.callback do
puts "Did it #{publication.inspect}"
EM.stop_event_loop
puts "#{__LINE__}: Reactor running: " + EM.reactor_running?.to_s
end
publication.errback do |error |
puts error.inspect
EM.stop_event_loop
end
end
end

Fayeclient.instance.pub
Fayeclient.instance.pub

Fayeclient.instance.em_thread.join

根据我的个人经验,无论如何,在 Rails 应用程序中处理 EventMachine 可能是一团糟,一些网络服务器使用 EM,其他则不使用,当你想从控制台测试时,它可能无法按预期工作。

我的解决方案是回退到 http 调用:

RestClient.post "http://localhost:#{Rails.configuration.faye_port}/faye", message: {foo: 'bar'}.to_json

如果您不需要从这段代码接收消息,我发现此解决方案更简单且易于定制。

关于ruby - Faye ruby​​ 客户端只发布一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25868491/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com