class BeerBot::IRCConnection

An instance of IRCConnection represents a specific connection to an irc server (for a given user/bot).

We also do some low-level bookkeeping, like returning pong and looking for welcome message.

Attributes

connection[RW]
echo[RW]
nick[RW]
port[RW]
queue[RW]

Queue containing received messages from the server.

readyq[RW]

Queue containing received messages from the server.

server[RW]
thread[RW]
writeq[RW]

Queue containing received messages from the server.

Public Class Methods

new(server:nil,port:6667,nick:'beerbot') click to toggle source
# File lib/beerbot/01.connect/IRCConnection.rb, line 26
def initialize server:nil,port:6667,nick:'beerbot'
  @echo = true
  @server = server
  @port = port
  @nick = nick
  @queue = Queue.new   # received messages
  @writeq = Queue.new  # messages to send out

  # This queue is only used at start up when the connection
  # to the irc server isn't ready yet:
  @readyq = Queue.new
  @ready = false
  @ready_blocks = []
  @ready_mutex = Mutex.new
  @write_mutex = Mutex.new

end

Public Instance Methods

close() click to toggle source
# File lib/beerbot/01.connect/IRCConnection.rb, line 127
def close
end
open(connection=nil) click to toggle source

Open and maintain the connection with an irc server.

If you pass in a connection object it will be used instead of opening a tcp socket. It should respond to whatever is called on @connection eg open,gets,write. Use for testing this class.

May throw errors.

  • @connection.eof? can throw things like ECONNRESET etc

# File lib/beerbot/01.connect/IRCConnection.rb, line 84
def open connection=nil
  @thread = Thread.new {
    loop do
      begin
        if connection then
          @connection = connection
          @connection.open(self.server, self.port)
        else
          @connection = TCPSocket.open(self.server, self.port)
        end
        self.write("USER #{@nick} #{@nick} #{@nick} :#{@nick}")
        self.write("NICK #{@nick}")
        while not @connection.eof? do
          str = @connection.gets()
          puts "<< #{str}" if @echo
          case str
          when /^PING (.*)$/
            self.write "PONG #{$1}"
          when / 001 / # ready
            self.ready!
          else
            self.queue.enq(str)
          end
        end
      rescue => e
        puts "Connection whoops: #{e}"
      end
      @ready = false
      puts "Sleeping #{10} then try again..."
      sleep 10
    end
  }
    
  @write_thread = Thread.new {
    loop do
      thing = @writeq.deq
      self.write thing
    end
  }

  @thread
end
ready!() click to toggle source

Flag the connection as ready.

Any blocks passed to ready? will now be executed.

# File lib/beerbot/01.connect/IRCConnection.rb, line 48
def ready!
  @ready_mutex.synchronize {
    unless @ready_blocks.empty? then
      @ready_blocks.each{|b| @readyq.enq(b)}
    end
    @ready = true
    while @readyq.size > 0
      block = @readyq.deq
      @ready_blocks.push(block)
      block.call
    end
  }
end
ready?(&block) click to toggle source
# File lib/beerbot/01.connect/IRCConnection.rb, line 62
def ready? &block
  return @ready unless block_given?
  @ready_mutex.synchronize {
    if @ready then
      block.call
    else
      @readyq.enq(block)
    end
  }
end
write(message) click to toggle source

Write out to the socket.

Chomps message and then adds “rn”.

# File lib/beerbot/01.connect/IRCConnection.rb, line 134
def write message
  case message
  when String
    message = message.chomp + "\r\n"
    puts ">> #{message}" if @echo
    @write_mutex.synchronize {
      @connection.print(message)
    }
  when Array
    message.each{|m| self.write(m) }
  when NilClass
  else
    puts "IRCConnection: can't process #{message}"
  end
end