ruby crawler_connection.rb
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby crawler_connection.rb相关的知识,希望对你有一定的参考价值。
require 'bitcoin'
class CrawlerConnection < EM::Connection
attr_accessor :message
attr_reader :host
attr_reader :port
def initialize(host, port)
@message = ''
@host = host
@port = port
end
def post_init
send_data(Bitcoin::Message::Version.new(remote_addr: "#{host}:#{port}").to_pkt)
end
# handle p2p message.
def receive_data(message)
begin
parse(message)
rescue Bitcoin::Message::Error => e
puts "invalid header magic. #{e.message}"
close
end
end
def parse(message)
@message += message
command, payload, rest = parse_header
return unless command
handle_command(command, payload)
@message = ""
parse(rest) if rest && rest.bytesize > 0
end
def parse_header
head_magic = Bitcoin.chain_params.magic_head
return if @message.nil? || @message.size < Bitcoin::MESSAGE_HEADER_SIZE
magic, command, length, checksum = @message.unpack('a4A12Va4')
raise Bitcoin::Message::Error, "invalid header magic. #{magic.bth}" unless magic.bth == head_magic
payload = @message[Bitcoin::MESSAGE_HEADER_SIZE...(Bitcoin::MESSAGE_HEADER_SIZE + length)]
return if payload.size < length
raise Bitcoin::Message::Error, "header checksum mismatch. #{checksum.bth}" unless Bitcoin.double_sha256(payload)[0...4] == checksum
rest = @message[(Bitcoin::MESSAGE_HEADER_SIZE + length)..-1]
[command, payload, rest]
end
def handle_command(command, payload)
begin
case command
when Bitcoin::Message::Version::COMMAND
on_version(Bitcoin::Message::Version.parse_from_payload(payload))
when Bitcoin::Message::VerAck::COMMAND
on_ver_ack
when Bitcoin::Message::Addr::COMMAND
on_addr(Bitcoin::Message::Addr.parse_from_payload(payload))
when Bitcoin::Message::Ping::COMMAND
on_ping(Bitcoin::Message::Ping.parse_from_payload(payload))
when Bitcoin::Message::Pong::COMMAND
on_pong(Bitcoin::Message::Pong.parse_from_payload(payload))
when Bitcoin::Message::Reject::COMMAND
on_reject(Bitcoin::Message::Reject.parse_from_payload(payload))
else
puts "other command receiverd : #{command}"
end
rescue Exception => e
puts "error occurred. #{e.message}"
puts e.backtrace
end
end
def on_version(version)
puts version.build_json
send_data(Bitcoin::Message::VerAck.new.to_pkt)
end
def on_ver_ack
puts "receive verack"
send_data(Bitcoin::Message::GetAddr.new.to_pkt)
end
def on_addr(addr)
puts addr.build_json
# TODO
end
def on_ping(ping)
puts "ping received: #{ping.build_json}"
send_data(ping.to_response.to_pkt)
end
def on_pong(pong)
puts "receive pong message. #{pong.build_json}"
end
def on_reject(reject)
puts reject.build_json
end
end
EM.run do
# Bitcoin.chain_params = :testnet
host = 'xxx'
port = Bitcoin.chain_params.default_port
EM.connect(host, port, CrawlerConnection, host, port)
end
以上是关于ruby crawler_connection.rb的主要内容,如果未能解决你的问题,请参考以下文章
Ruby 25 岁了!Ruby 之父说 Ruby 3 有望 3 倍提速