Sha256: 4957a23f40ca68d91c7cd5ece904c7e6a9a55f6bb1f37acf9c4d25ca0e1acc2a

Contents?: true

Size: 1.95 KB

Versions: 1

Compression:

Stored size: 1.95 KB

Contents

require 'socket'
require_relative 'tattler'

module Buschtelefon
  class NetTattler < Tattler
    attr_accessor :port, :socket

    def initialize(port: 0)
      super()
      @socket = UDPSocket.new
      @socket.bind('127.0.0.1', port)
      @port = @socket.local_address.ip_port
    end

    def listen(&_callback)
      puts "Started UDP server on #{@port}..."

      Socket.udp_server_loop_on([@socket]) do |message, message_source|
        remote_tattler = find_or_build_remote_tattler(
          host: message_source.remote_address.ip_address,
          port: message_source.remote_address.ip_port
        )

        if message == "\x05"
          #puts "#{@port} got inquiry from #{remote_tattler}. Is connected to #{@connections.inspect}"
          handle_knowledge_inquiry(remote_tattler)
        else
          gossip = Gossip.new(message)
          handle_incoming_gossip(gossip)
          yield(gossip, remote_tattler) if block_given?
        end
      end
    end

    def connect_remote(host:, port:)
      find_or_build_remote_tattler(host: host, port: port).tap do |remote_tattler|
        connect(remote_tattler)
      end
    end

    def inquire_remote_neighbors
      remote_connections.each { |remote_tattler| remote_tattler.inquire }
    end

    def remote_connections
      @connections.select { |tattler| tattler.is_a?(RemoteTattler) }
    end

    def to_s
      "127.0.0.1:#{@port}"
    end

    private

    def handle_incoming_gossip(gossip)
      feed(gossip)
    end

    # We just give out everything to the outbound port of the inquiry source
    def handle_knowledge_inquiry(remote_tattler)
      transfer_knowledge(remote_tattler)
    end

    def find_or_build_remote_tattler(host:, port:)
      remote_connections.find { |t| t.host == host && t.port == port  } || build_remote_tattler(host: host, port: port)
    end

    def build_remote_tattler(host:, port:)
      RemoteTattler.new(host: host, port: port, outbound_socket: @socket)
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
buschtelefon-0.4.0 lib/buschtelefon/net_tattler.rb