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 倍提速

如何学习ruby?Ruby学习技巧分享

ruby Ruby脚本,看看是否用openssl编译了ruby

什么是ruby?

ruby和ruby ee

ruby入门知识:了解ruby历史及特性