### Home Classes Methods

### In Files

- lib/rbot/ircsocket.rb

### Parent

Object

### Namespace

- CLASS Irc::Socket::IdentityFilter

### Methods

- ::new
- #clearq
- #connect
- #connected?
- #emergency_puts
- #filter=
- #flush
- #gets
- #handle_socket_error
- #puts_critical
- #queue
- #select
- #shutdown
- #writer_loop

### Class/Module Index

Quicksearch

- Irc
- Irc::AsciiCasemap
- Irc::BanlistMessage
- Irc::BasicUserMessage
- Irc::Bot
- Irc::Bot::Auth
- Irc::Bot::Auth::BotOwnerClass
- Irc::Bot::Auth::BotUser
- Irc::Bot::Auth::Command
- Irc::Bot::Auth::DefaultBotUserClass
- Irc::Bot::Auth::InvalidPassword
- Irc::Bot::Auth::ManagerClass
- Irc::Bot::Auth::PermissionSet
- Irc::Bot::Config
- Irc::Bot::Config::ArrayValue
- Irc::Bot::Config::BooleanValue
- Irc::Bot::Config::EnumValue
- Irc::Bot::Config::FloatValue
- Irc::Bot::Config::IntegerValue
- Irc::Bot::Config::ManagerClass
- Irc::Bot::Config::StringValue
- Irc::Bot::Config::Value
- Irc::Bot::Config::Wizard
- Irc::Bot::DataFilter
- Irc::Bot::DataStream
- Irc::Bot::Language
- Irc::Bot::MessageMapper
- Irc::Bot::MessageMapper::Failure
- Irc::Bot::MessageMapper::FriendlyFailure
- Irc::Bot::MessageMapper::NoActionFailure
- Irc::Bot::MessageMapper::NoMatchFailure
- Irc::Bot::MessageMapper::NotPrivateFailure
- Irc::Bot::MessageMapper::NotPublicFailure
- Irc::Bot::MessageMapper::PartialMatchFailure
- Irc::Bot::MessageParameter
- Irc::Bot::MessageTemplate
- Irc::Bot::Plugins
- Irc::Bot::Plugins::BotModule
- Irc::Bot::Plugins::CoreBotModule
- Irc::Bot::Plugins::Plugin
- Irc::Bot::Plugins::PluginManagerClass
- Irc::Bot::Plugins::RecurseTooDeep
- Irc::Bot::Plugins::RemoteBotModule
- Irc::Bot::Plugins::RemoteCoreBotModule
- Irc::Bot::Plugins::RemotePlugin
- Irc::Bot::Registry
- Irc::Bot::Registry::Accessor
- Irc::Bot::RemoteDispatcher
- Irc::Bot::RemoteMessage
- Irc::Bot::RemoteObject
- Irc::Bot::Wordlist
- Irc::BotConfig
- Irc::Casemap
- Irc::Channel
- Irc::Channel::Mode
- Irc::Channel::ModeHash
- Irc::Channel::ModeTypeA
- Irc::Channel::ModeTypeB
- Irc::Channel::ModeTypeC
- Irc::Channel::ModeTypeD
- Irc::Channel::Topic
- Irc::Channel::UserMode
- Irc::ChannelList
- Irc::Client
- Irc::DBHash
- Irc::DBTree
- Irc::InviteMessage
- Irc::JoinMessage
- Irc::KickMessage
- Irc::MessageQueue
- Irc::ModeChangeMessage
- Irc::MotdMessage
- Irc::NamesMessage
- Irc::Netmask
- Irc::NetmaskDb
- Irc::NetmaskDb::Tree
- Irc::NetmaskList
- Irc::NickMessage
- Irc::NoSuchTargetMessage
- Irc::NoticeMessage
- Irc::PartMessage
- Irc::PrivMessage
- Irc::QueueRing
- Irc::QuitMessage
- Irc::RfcCasemap
- Irc::Server
- Irc::ServerOrCasemap
- Irc::Socket
- Irc::Socket::IdentityFilter
- Irc::StrictRfcCasemap
- Irc::TopicMessage
- Irc::UnknownMessage
- Irc::User
- Irc::UserList
- Irc::UserMessage
- Irc::Utils
- Irc::Utils::HttpUtil
- Irc::Utils::HttpUtil::CachedObject
- Irc::Utils::ParseTime
- Irc::WelcomeMessage
- Irc::WhoisMessage
- BDB
- BDB::CIBtree
- MonitorMixin
- MonitorMixin::ConditionVariable
- Net
- Net::HTTPResponse
- Regexp
- Regexp::Irc
- Singleton
- Singleton::SingletonClassMethods
- Timer
- Timer::Action
- TokyoCabinet
- TokyoCabinet::CIBDB
- UnicodePlugin
- UnicodePlugin::UnicodeFilter
- Array
- ArrayOf
- AuthModule
- BasicsModule
- ConditionVariable
- ConfigModule
- DottedIndex
- Enumerable
- Exception
- FiltersModule
- GetText
- GetTextVersionError
- HttpUtilPlugin
- IrcLogModule
- Module
- Numeric
- Object
- Range
- RemoteModule
- ServerError
- String
- Symbol
- UserDataModule
- WordlistModule
- YAML

No matching classes.

# Irc::Socket

wrapped TCPSocket for communication with the server. emulates a subset of TCPSocket functionality

### Constants

MAX_IRC_SEND_PENALTY

### Attributes

bytes_received[R]

total number of bytes received from the irc server

bytes_sent[R]

total number of bytes sent to the irc server

filter[R]

an optional filter object. we call @filter.in(data) for all incoming data and @filter.out(data) for all outgoing data

lines_received[R]

total number of lines received from the irc server

lines_sent[R]

total number of lines sent to the irc server

penalty_pct[RW]

penalty multiplier (percent)

server_uri[R]

normalized uri of the current server

throttle_bytes[R]

accumulator for the throttle

### Public Class Methods

new(server_list, host, opts={}) click to toggle source

server_list | list of servers to connect to
host | optional local host to bind to (ruby 1.7+ required)

create a new Irc::Socket

    # File lib/rbot/ircsocket.rb, line 277
    def initialize(server_list, host, opts={})
      @server_list = server_list.dup
      @server_uri = nil
      @conn_count = 0
      @host = host
      @sock = nil
      @filter = IdentityFilter.new
      @spooler = false
      @lines_sent = 0
      @lines_received = 0
      @ssl = opts[:ssl]
      @penalty_pct = opts[:penalty_pct] || 100
    end

### Public Instance Methods

clearq() click to toggle source

    # File lib/rbot/ircsocket.rb, line 379
    def clearq
      @sendq.clear
    end

connect() click to toggle source

open a TCP connection to the server

    # File lib/rbot/ircsocket.rb, line 296
    def connect
      if connected?
        warning "reconnecting while connected"
        return
      end
      srv_uri = @server_list[@conn_count % @server_list.size].dup
      srv_uri = 'irc://' + srv_uri if !(srv_uri =~ /:\/\//)
      @conn_count += 1
      @server_uri = URI.parse(srv_uri)
      @server_uri.port = 6667 if !@server_uri.port
      debug "connection attempt \##{@conn_count} (#{@server_uri.host}:#{@server_uri.port})"

      if(@host)
        begin
          sock=TCPSocket.new(@server_uri.host, @server_uri.port, @host)
        rescue ArgumentError => e
          error "Your version of ruby does not support binding to a "
          error "specific local address, please upgrade if you wish "
          error "to use HOST = foo"
          error "(this option has been disabled in order to continue)"
          sock=TCPSocket.new(@server_uri.host, @server_uri.port)
        end
      else
        sock=TCPSocket.new(@server_uri.host, @server_uri.port)
      end
      if(@ssl)
        require 'openssl'
        ssl_context = OpenSSL::SSL::SSLContext.new()
        ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
        sock = OpenSSL::SSL::SSLSocket.new(sock, ssl_context)
        sock.sync_close = true
        sock.connect
      end
      @sock = sock
      @last_send = Time.new
      @flood_send = Time.new
      @burst = 0
      @sock.extend(MonitorMixin)
      @sendq = MessageQueue.new
      @qthread = Thread.new { writer_loop }
    end

connected?() click to toggle source

    # File lib/rbot/ircsocket.rb, line 291
    def connected?
      !@sock.nil?
    end

emergency_puts(message, penalty = false) click to toggle source

used to send lines to the remote IRCd by skipping the queue message: IRC message to send it should only be used for stuff that *must not* be queued, i.e. the initial PASS, NICK and USER command or the final QUIT message

    # File lib/rbot/ircsocket.rb, line 343
    def emergency_puts(message, penalty = false)
      @sock.synchronize do
        # debug "In puts - got @sock"
        puts_critical(message, penalty)
      end
    end

filter=(f) click to toggle source

set filter to identity, not to nil

    # File lib/rbot/ircsocket.rb, line 270
    def filter=(f)
        @filter = f || IdentityFilter.new
    end

flush() click to toggle source

flush the TCPSocket

    # File lib/rbot/ircsocket.rb, line 384
    def flush
      @sock.flush
    end

gets() click to toggle source

get the next line from the server (blocks)

    # File lib/rbot/ircsocket.rb, line 359
    def gets
      if @sock.nil?
        warning "socket get attempted while closed"
        return nil
      end
      begin
        reply = @filter.in(@sock.gets)
        @lines_received += 1
        reply.strip! if reply
        debug "RECV: #{reply.inspect}"
        return reply
      rescue Exception => e
        handle_socket_error(:RECV, e)
      end
    end

handle_socket_error(string, e) click to toggle source

    # File lib/rbot/ircsocket.rb, line 350
    def handle_socket_error(string, e)
      error "#{string} failed: #{e.pretty_inspect}"
      # We assume that an error means that there are connection
      # problems and that we should reconnect, so we
      shutdown
      raise SocketError.new(e.inspect)
    end

queue(msg, chan=nil, ring=0) click to toggle source

    # File lib/rbot/ircsocket.rb, line 375
    def queue(msg, chan=nil, ring=0)
      @sendq.push msg, chan, ring
    end

select(timeout=nil) click to toggle source

Wraps Kernel.select on the socket

    # File lib/rbot/ircsocket.rb, line 389
    def select(timeout=nil)
      Kernel.select([@sock], nil, nil, timeout)
    end

shutdown(how=2) click to toggle source

shutdown the connection to the server

    # File lib/rbot/ircsocket.rb, line 394
    def shutdown(how=2)
      return unless connected?
      @qthread.kill
      @qthread = nil
      begin
        @sock.close
      rescue Exception => e
        error "error while shutting down: #{e.pretty_inspect}"
      end
      @sock = nil
      @sendq.clear
    end

### Private Instance Methods

puts_critical(message, penalty=false) click to toggle source

same as puts, but expects to be called with a lock held on @sock

    # File lib/rbot/ircsocket.rb, line 431
    def puts_critical(message, penalty=false)
      # debug "in puts_critical"
      begin
        debug "SEND: #{message.inspect}"
        if @sock.nil?
          error "SEND attempted on closed socket"
        else
          # we use Socket#syswrite() instead of Socket#puts() because
          # the latter is racy and can cause double message output in
          # some circumstances
          actual = @filter.out(message) + "\n"
          now = Time.new
          @sock.syswrite actual
          @last_send = now
          @flood_send = now if @flood_send < now
          @flood_send += message.irc_send_penalty*@penalty_pct/100.0 if penalty
          @lines_sent += 1
        end
      rescue Exception => e
        handle_socket_error(:SEND, e)
      end
    end

writer_loop() click to toggle source

    # File lib/rbot/ircsocket.rb, line 409
    def writer_loop
      loop do
        begin
          now = Time.now
          flood_delay = @flood_send - MAX_IRC_SEND_PENALTY - now
          delay = [flood_delay, 0].max
          if delay > 0
            debug "sleep(#{delay}) # (f: #{flood_delay})"
            sleep(delay)
          end
          msg = @sendq.shift
          debug "got #{msg.inspect} from queue, sending"
          emergency_puts(msg, true)
        rescue Exception => e
          error "Spooling failed: #{e.pretty_inspect}"
          debug e.backtrace.join("\n")
          raise e
        end
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.