Class: BeerBot::IRCConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/beerbot/01.connect/IRCConnection.rb

Overview

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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server: nil, port: 6667, nick: 'beerbot') ⇒ IRCConnection

Returns a new instance of IRCConnection.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 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

Instance Attribute Details

#connectionObject

Returns the value of attribute connection.



23
24
25
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 23

def connection
  @connection
end

#echoObject

Returns the value of attribute echo.



24
25
26
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 24

def echo
  @echo
end

#nickObject

Returns the value of attribute nick.



23
24
25
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 23

def nick
  @nick
end

#portObject

Returns the value of attribute port.



23
24
25
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 23

def port
  @port
end

#queueObject

Queue containing received messages from the server.



22
23
24
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 22

def queue
  @queue
end

#readyqObject

Queue containing received messages from the server.



22
23
24
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 22

def readyq
  @readyq
end

#serverObject

Returns the value of attribute server.



23
24
25
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 23

def server
  @server
end

#threadObject

Returns the value of attribute thread.



23
24
25
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 23

def thread
  @thread
end

#writeqObject

Queue containing received messages from the server.



22
23
24
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 22

def writeq
  @writeq
end

Instance Method Details

#closeObject



127
128
# File 'lib/beerbot/01.connect/IRCConnection.rb', line 127

def close
end

#open(connection = nil) ⇒ Object

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



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# 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!Object

Flag the connection as ready.

Any blocks passed to ready? will now be executed.



48
49
50
51
52
53
54
55
56
57
58
59
60
# 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) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
69
70
71
# 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) ⇒ Object

Write out to the socket.

Chomps message and then adds “rn”.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# 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