Heh--you're welcome. But please don't let me bully you into dropping rails--I
don't understand your goals as well as you do. ;-) I'm just trying to explain
options. I frankly don't understand rails well enough to know when/how objects
live beyond individual http requesst/response cycles. My guess is that your
socket server thingy needs to be independent of that in order to handle
incoming connections reliably.
I can say that it is possible to add class *methods* to a descendant of
AR::Base--frx, in the below find_by_fragment is a class method.
class SpecificTherapeuticClass < ActiveRecord::Base
has_many :ingredients
belongs_to :general_therapeutic_class
def self.find_by_fragment(frag)
frag += "%"
self.find(:all, :conditions => ["description like :frag", {:frag =>
frag}])
end
end
I'm not totally sure I follow your code below, but one thing jumps out--this
line:
cattr_accessor :connection, :cert_name, :cert
Defines *class* methods & vars for those attributes. So you'd say, e.g.
ConnectionManager.cert = "/bibbity/bobbity/boo.pem" and that bit of data is
entirely independent of any particular instance of ConnectionManager. But
initialize is an *instance* method--it gets called in the context of a new
instance of ConnectionManager. So the line "cert = File.read..." in your
initialize method is just setting a local var 'cert' which will die as soon as
the initialize call is over. If you want to define instance methods
connection, cert_name & cert, you'd use the (native ruby) attr_accessor method
(and you may want to call it as self.cert, just to make it totally clear to the
interpreter that you intend to call a method rather than set a local var).
Maybe that helps?
Cheers,
-Roy
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Steve Hull
Sent: Thursday, May 21, 2009 5:06 PM
To: [email protected]
Subject: [Rails] Re: How to keep persistent socket connections?
Roy --
Thank you for that example!! I guess I'll give that a shot :)
It still hurts my heart that this doesn't appear to be possible with Rails. :(
One followup question, if I may:
Why is it that class variables don't behave as I expect them to? So since it
appears that adding class attributes (inheritable or not) to a descendent of
ActiveRecord is unsupported, I added a new Class (inheriting from Object) and
put it in /lib:
class ConnectionManager
HOST = "the.host.com"
PATH = '/'
PORT = 2195
PASSPHRASE = "foobar"
CACERT = File.expand_path(File.dirname(__FILE__) +
"certs/ca.the.host.com.crt")
USERAGENT = 'Mozilla/5.0 (ConnectionManager Ruby on Rails 0.1)'
cattr_accessor :connection, :cert_name, :cert
self.cert_name = "my_pem_file.pem"
def initialize
super
cert = File.read("config/#{cert_name}") if
File.exists?("config/#{cert_name}")
puts "cert = #{cert.inspect}"
if connection.nil?
puts "Connecting now!!"
ctx = OpenSSL::SSL::SSLContext.new
ctx.key = OpenSSL::PKey::RSA.new(cert, PASSPHRASE)
ctx.cert = OpenSSL::X509::Certificate.new(cert)
s = TCPSocket.new(HOST, PORT)
connection = OpenSSL::SSL::SSLSocket.new(s, ctx)
connection.sync = true
connection.connect
end
end
end
But when I try to use this in my class that inherits from ActiveRecord,
like this:
def send
ssl = cm.class.connection
logger.info "ssl = #{ssl.inspect}"
ssl.write(self.message_for_sending)
rescue SocketError => error
raise "Error while sending: #{error}"
end
First I got an error and I realized that my ConnectionManager's
initialize method wasn't being called. So I added a line to get an
instance of ConnectionManager, just so that initialize would be called:
def send_notification
cm = ConnectionManager.new
ssl = cm.class.connection
logger.info "ssl = #{ssl.inspect}"
ssl.write(self.message_for_sending)
rescue SocketError => error
raise "Error while sending notifications: #{error}"
end
I could tell from my log ("Connecting Now!!" appeared) that initialize
had been called. But I'm still getting an error:
You have a nil object when you didn't expect it! The error occurred
while evaluating nil.write
Clearly ConnectionManager.connection is returning null. In Java, once
you've used a class, its static vars are instantiated and hold their
values. It seems that in Ruby, the class's static vars are
instantiated/sandboxed in each .rb file. Am I correct here, or no?
Thanks again for the example code Roy!
-Steve
--
Posted via http://www.ruby-forum.com/.
GHC Confidentiality Statement
This message and any attached files might contain confidential information
protected by federal and state law. The information is intended only for the
use of the individual(s) or entities originally named as addressees. The
improper disclosure of such information may be subject to civil or criminal
penalties. If this message reached you in error, please contact the sender and
destroy this message. Disclosing, copying, forwarding, or distributing the
information by unauthorized individuals or entities is strictly prohibited by
law.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby
on Rails: Talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---