- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
堆栈:Ruby 2.3.1,Rack,瘦
简单的 websocket 服务器:
require 'redis'
require 'em-hiredis'
require 'faye/websocket'
require 'json'
ws_channel = {}
App = lambda do |env|
$redis ||= EM::Hiredis.connect('redis://127.0.0.1:6379')
if Faye::WebSocket.websocket?(env)
ws = Faye::WebSocket.new(env, nil,
headers: {'Access-Control-Allow-Origin' => '*'},
ping: 15
)
ws.on :open do |event|
puts 'client connected'
query_string = event.current_target.env['REQUEST_PATH'].gsub(/[^a-z0-9\-_\/]/, '')
ws_channel[query_string] ||= EM::Channel.new
pubsub = $redis.pubsub
puts "subscribing to ws channel: ws:#{query_string}"
sid = ws_channel[query_string].subscribe do |msg|
puts "WS -> ws:#{query_string}/ #{sid} #{ws_channel[query_string]}"
ws.send msg
end
puts "subscribing to redis: #{query_string}"
pubsub.subscribe(query_string) do |msg|
puts "REDIS -> ws:#{query_string}/"
$redis.setex(query_string, 60, msg)
ws_channel[query_string].push msg
end
EventMachine.add_periodic_timer(5) do
ws.send ({ :ts => Time.now.to_i}.to_json) if ws
end
ws.on :close do |event|
puts "client ##{query_string} disconnected"
pubsub.unsubscribe(query_string) if pubsub
ws_channel[query_string].unsubscribe(sid) if ws_channel[query_string]
ws = nil
pubsub = nil
end
end
ws.rack_response
end
end
config.ru:
require 'rubygems'
require 'bundler/setup'
require 'logger'
require File.expand_path('../app', __FILE__)
Faye::WebSocket.load_adapter('thin')
run App
启动服务器:
bundle exec thin -p 9292 -R config.ru start
发行条件:
我的解决方法是在连接打开时取消订阅/重新订阅。所以:
pubsub = $redis.pubsub
pubsub.unsubscribe(query_string) if pubsub
pubsub = $redis.pubsub
但这引入了另一个问题:当一个选项卡关闭时,数据停止到达其他选项卡大约 30 秒。 WS 连接永远不会关闭,我可以在 JS 控制台中看到 5 秒的 ping。
redis-cli $> PUBSUB NUMSUB <channel>
目标功能:
最佳答案
为每个 WS 连接创建一个唯一的 EM channel 并取消订阅 ws.close 上的特定过程,似乎可以完成这项工作:
require 'redis'
require 'em-hiredis'
require 'faye/websocket'
require 'json'
App = lambda do |env|
$redis ||= EM::Hiredis.connect('redis://127.0.0.1:6379')
$pubsub ||= $redis.pubsub
if Faye::WebSocket.websocket?(env)
ws = Faye::WebSocket.new(env, nil,
headers: {'Access-Control-Allow-Origin' => '*'},
ping: 15
)
ws.on :open do |event|
puts 'client connected'
query_string = event.current_target.env['REQUEST_PATH'].gsub(/[^a-z0-9\-_\/]/, '')
channel = EM::Channel.new
puts "subscribing to ws channel: ws:#{query_string}"
sid = channel.subscribe do |msg|
puts "WS -> ws:#{query_string}/ #{sid} #{channel}"
ws.send msg
end
puts "subscribing to redis: #{query_string}"
subs = {}; r_callback = rand(Time.now.to_i)
subs[r_callback] = Proc.new { |msg|
puts "REDIS -> ws:#{query_string}/"
$redis.setex(query_string, 60, msg)
channel.push msg
}
$pubsub.subscribe(query_string, subs[r_callback])
#puts $pubsub.inspect
ws.on :close do |event|
puts "client ##{query_string} disconnected"
$pubsub.unsubscribe_proc(query_string, subs[r_callback]) if $pubsub
puts "Unsubscribed proc: #{subs[r_callback]}"
channel.unsubscribe(sid) if channel
ws = nil
end
end
ws.rack_response
end
end
关于ruby - 发送给 EventMachine pubsub 订阅者的重复数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42489988/
我的控制台上出现以下错误 root@comp09:~# gem install eventmachine Building native extensions. This could take a
我在 JRuby 中安装了 EventMachine(我使用的是 Win32)。当我尝试服务器示例时,出现错误 require 'eventmachine' 错误是: C:\dev\em>jruby
我有一些 Deferrables,当它们全部完成时我需要在回调中做一些事情。 defers[0].callback do defers[1].callback do defer
我正在编写一个应用程序,它使用 EventMachine 来中继来自服务的命令。我想重新使用与服务的连接(而不是为每个新请求重新创建它)。该服务从模块方法启动,并且该模块提供给 EventMachin
更新: 我找到了简单的答案,这完全是我自己的错:我将上面的代码存储在一个名为“eventmachine.rb”的文件中。因此,当我需要“eventmachine”时,它只是导入了相同的文件,其中不包含
好的,我有代码在后台使用 Cramp\Tramp => EventMachine。代码: class RetrieveController 0.12' gem 'tramp', '~> 0.2' g
每个人总是明确提到 next_tick 将在主线程中执行。但是定时器和回调/错误反馈呢?它们是否也保证在主线程中运行? 最佳答案 无论 Ruby 版本如何,EM 在 react 器线程内运行除 EM.
在 ruby 1.9.2-p290 上编译 eventmachine 0.12.10 时出现以下错误输出: g++ -shared -o rubyeventmachine.so binder.o cm
我收到以下错误: eventmachine.rb:534:in `start_tcp_server': no acceptor (port is in use or requires root pri
我有一个使用 eventmachine 编写的小型 HTTP 服务器脚本,它需要调用外部脚本/命令并通过反引号 (``) 调用。当提供不运行反引号代码的请求时,一切都很好,但是,一旦我的 EM 代码执
我写了一个像这样的简单的 EventMachine 服务器: EventMachine.run do EventMachine::WebSocket.start(:host => HOST, :p
“run” block 是否在 EM 中作为一个整体执行(没有上下文切换)?在此示例中,if 子句中是否存在竞争条件? EventMachine.run { @current_value = 0
获取端口已在使用错误。 require 'em-websocket' EM.run { EM::WebSocket.run(:host => "192.168.1.100", :port =>
我对一般编程还很陌生,我在客户端和服务器端都使用 EventMachine 来打开它们之间的 websocket 连接。 我的问题出在客户端,以及由于网络连接问题导致连接丢失时。 def websoc
如何终止 EventMachine 中正在运行的进程?下面是一个示例,我正在启动 10 个进程,然后我试图将它们全部删除(但它不起作用)。我的目标是不要有“完成”输出。 require "rubyge
我使用 EventMachine LineText2 协议(protocol),我想在每次按下键盘上的字符时触发 receive_line 方法,而不仅仅是在输入新行时触发。有没有办法改变这种默认行为
这是我的代码: EventMachine.run { conn = EM::Protocols::HttpClient2.connect request.host, 80 req =
我正在研究使用 EventMachine 支持的 twitter-stream rubygem 来跟踪和捕获推文。我对整个事件编程有点陌生。我如何判断我在事件循环中所做的任何处理是否导致我落后?有
我的第一个问题是关于 Ruby 的。我正在尝试测试 Reactor 循环内的 EventMachine 交互 - 我想它可以归类为“功能”测试。 假设我有两个类 - 服务器和客户端。我想测试双方 -
我正在使用合适的 Redis EM gem(在我的例子中为“em-hiredis”)读取 EventMachine react 器循环中的 Redis 集,并且必须检查某些 Redis 集是否包含级联
我是一名优秀的程序员,十分优秀!