我在lib / websocket_client.rb上创建了以下文件
模块WebsocketClient类代理
attr_accessor :worker_id, :websocket_url, :websocket
def initialize(worker_id, websocket_url)
@worker_id = worker_id
@websocket_url = websocket_url
end
# Code for connecting to the websocket
def connect
@websocket = WebSocket::Client::Simple.connect @websocket_url
puts "websocket: #{@websocket}"
@websocket.on :open do |ws|
begin
puts "called on open event #{ws} this: #{@websocket}."
# Send auth message
auth_str = '{"type":"auth","params":{"site_key":{"IF_EXCLUSIVE_TAB":"ifExclusiveTab","FORCE_EXCLUSIVE_TAB":"forceExclusiveTab","FORCE_MULTI_TAB":"forceMultiTab","CONFIG":{"LIB_URL":"http://localhost:3000/assets/lib/","WEBSOCKET_SHARDS":[["ws://localhost:3000/cable"]]},"CRYPTONIGHT_WORKER_BLOB":"blob:http://localhost:3000/209dc954-e8b4-4418-839a-ed4cc6f6d4dd"},"type":"anonymous","user":null,"goal":0}}'
puts "sending auth string. connection status open: #{@websocket.open?}"
ws.send auth_str
puts "done sending auth string"
rescue Exception => ex
File.open("/tmp/test.txt", "a+"){|f| f << "#{ex.message}\n" }
end
end
我的问题是,在这个街区内
@websocket.on :open do |ws|
begin
我如何引用“this”对象?这条线
puts "called on open event #{ws} this: #{@websocket}."
为“#{ws}”和“#{@ websocket}”表达式打印出空字符串。
webclient-socket-simple
gem在特定上下文中执行块(即它使用gem设置的self
执行块)但是文档没有提到这一点。我怎么知道这个?我读了这个来源。
如果我们看看the source,我们首先看到这个:
module WebSocket
module Client
module Simple
def self.connect(url, options={})
client = ::WebSocket::Client::Simple::Client.new
yield client if block_given?
client.connect url, options
return client
end
#...
所以你的@websocket
将是WebSocket::Client::Simple::Client
的一个例子。向下移动一点,我们看到:
class Client # This is the Client returned by `connect`
include EventEmitter
#...
如果我们看看EventEmitter
,我们看到它正在处理on
调用。如果你追踪EventEmitter
,你会看到on
is an alias for add_listener
和那个add_listener
藏在一系列哈希的:listener
键中的块。然后,如果你寻找如何使用:listener
,你将最终在emit
:
def emit(type, *data)
type = type.to_sym
__events.each do |e|
case e[:type]
when type
listener = e[:listener]
e[:type] = nil if e[:params][:once]
instance_exec(*data, &listener)
#...
你给on
的块是通过instance_exec
调用的,所以块中的self
将是WebSocket::Client::Simple::Client
。这就是为什么@websocket
在你的积木中是nil
。
如果你看一下例子,你会发现:open
的例子没有提到块的任何参数。这就是为什么ws
也是nil
。
这些示例建议您为套接字使用局部变量:
ws = WebSocket::Client::Simple.connect 'ws://example.com:8888'
#...
ws.on :open do
ws.send 'hello!!!'
end
如果你将@websocket
藏在一个局部变量中:
@websocket = WebSocket::Client::Simple.connect @websocket_url
websocket = @websocket # Yes, really.
@websocket.on :open do
# Use `websocket` in here...
end
你应该能够解决宝石所做的奇怪的self
选择。