Threaded Networking in Ruby

    Today in #ruby on Freenode someone who was working on an IRC bot was showing off their code and pointed out that it couldn't maintain more than one connection at a time. While I already had a IRC specific chunk of code I used myself to show him, I figured a more general solution would be a good idea. As such I figured I'd encapsulate a network connection in a simple class, so here you go!

# General purpose wrapper for network connections
class NetworkConnection
  attr_reader :hostname, :port, :thread
  # Creates a new instance of NetworkConnection with the
  # specified hostname and port
  def initialize(hostname, port)
    @hostname = hostname
    @port = port
  end
  # Connects to the specified hostname and port given in new
  def connect
    @thread = Thread.new do
      @socket = TCPSocket.new(@hostname, @port)
      @socket.each { |line|  @block.call(line) }
    end
  end
  # Closes the socket
  def disconnect
    @socket.close
  end
  # Takes a block of code to be called on each line recieved
  def on_recv(&block)
    @block = block
  end
  # Sends text to the socket
  def send(text)
    @socket.send(text + '\r\n', 0)
  end
end

So now, the usual sample usage!

connection = NetworkConnection.new("irc.freenode.net", 6667)
connection.on_recv { |line| puts line }
connection.connect

Obviously this sample code will exit right after the connection is made, since the connection is maintained in a separate ruby thread. I'll leave it up to you to actually find some use in this, but there you go.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

GServer

Doesn't Ruby's included GServer library do something similar?

snuxoll's picture

Not that I'm aware of, but

Not that I'm aware of, but this was meant to be a simple way to show how to do threaded networking in ruby apps, so take it for what it's worth.

Stefan Nuxoll

rick

what is @thread's initial value? It's not mentioned anywhere else in the class.

snuxoll's picture

@thread isn't made until

@thread isn't made until NetworkConnection#connect is called, and when it is created it's the instance of the worker thread that listens to the socket for incoming data.

Edit: Aaah, I see why you asked that, I made a mistake in my code.

@thread << Thread.new do

should be
@thread = Thread.new do

I have corrected it in the post now.

Stefan Nuxoll

queaeuk loxqsyx

ytlqwtzvzs, http://www.insfakhpvx.com axyndxcnfo

mpwhuniqtt

pykrqguhdu, Hi, you have a great site! http://www.zwiddtrxom.com mpwhuniqtt , thanks!

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".

More information about formatting options