Problem with eventmachine

I have following code, the problem is, when i start a connection to
the socket through telnet, the data send by the server i get as
usual, but when i try to do the same through ruby code, the data send
by the server won’t come to the client…until the server is shutdown.

def receive_data data
data = data.chomp.strip
if is_symbol?(data)
add_symbol(data)
local_connection = self
start_send_thread(local_connection)
end
end

def start_send_thread(local_connection)
unless @send_started
p “Trying to send the data”
@send_started = true
@local_thread = Thread.new do
loop do
broadcast_data(local_connection)
sleep(0.1)
p “I am running”
end
end
end
end

def broadcast_data(local_connection)
for x in @local_symbols
local_connection.send_data “#{x}”+rand(10).to_s
end
end

def unbind
p “Client closed the connection”
Thread.kill(@local_thread)
end

On 9/19/06, hemant [email protected] wrote:

I have following code, the problem is, when i start a connection to
the socket through telnet, the data send by the server i get as
usual, but when i try to do the same through ruby code, the data send
by the server won’t come to the client…until the server is shutdown.

Ok that was one stupid wtf…
i forgot to put “\n” in the end of the string, i guess.

On 9/19/06, Francis C. [email protected] wrote:

If you really want to hammer your telnet client with random data based
on @local_symbols, use EventMachine#add_periodic_timer rather than
spinning a thread.

Thanks for replying.
Random values were just the placeholders, the actual data would be
more important i guess. But my understanding of add_periodic_timer
says that, it would be global to entire program. But what i want is
basically, a method which would be client specific. By being client
specific, I mean…each connection, should have a callback, which
would start sending the data. Please correct me, If i am wrong.

Basically what i want is…push the data to the clients
asynchronously. Using recieve_data I can change @local_symbols and
hence the data pushed to the client should change accordingly.

So, How do i do this?

On 9/19/06, hemant [email protected] wrote:

I have following code, the problem is, when i start a connection to
the socket through telnet, the data send by the server i get as
usual, but when i try to do the same through ruby code, the data send
by the server won’t come to the client…until the server is shutdown.

Two points:
First, if you’re connecting to this program using telnet, the behavior
will depend on the platform that you run telnet on. The telnet client
on Windows sends data byte-by-byte as you type it in. On Linux, Mac or
other Unix, telnet buffers the data line by line.

Second, and extremely important: you do not need to spin a thread to
send your data. The whole point of EventMachine is that it allows you
to handle many connections at once, without using threads. Threads
slow your program down and make it harder to debug.

If you really want to hammer your telnet client with random data based
on @local_symbols, use EventMachine#add_periodic_timer rather than
spinning a thread.

Sorry if I missed you, Hemant- I was hoping to get a bit more
information on your home-grown data-vending server. If the protocol is
appropriate for EM, then you can implement your push server without
spinning any threads.

On 9/19/06, hemant [email protected] wrote:

Basically what i want is…push the data to the clients
asynchronously. Using recieve_data I can change @local_symbols and
hence the data pushed to the client should change accordingly.

So, How do i do this?

The answer depends on when your asynch data becomes available. If it
happens
on a time basis, then #add_periodic_timer is the right solution.
#add_periodic_timer (or #add_timer) is client-specific because you pass
it a
block, which is of course a closure, so it has access to your local
scope.
The following code will do what you want. Try it with multiple
connections
and see:

def receive_data data
local_scope_data = “whatever\n”
EventMachine.add_periodic_timer(2) {
send_data( local_scope_data )
}
end

If your async data comes from other events in the system (like calls to
web-services) then you can use EventMachine’s Deferrable pattern, which
works much like the one in Twisted, but easier to use because it’s Ruby
:-).
If you want to do that, feel free to write me offlist and I’ll show you
how
to use it.

Unrelated comment: I’m finding that a lot of people have a need to
accept
network connections, receive data from remote clients, and then respond
with
data that is aggregated from other network services (databases, other
web
sites, etc). This is exactly the kind of pattern EventMachine is good
for.
I’m thinking about adding some specific API support tosimplify this
pattern,
especially for use within Rails apps (where your controller may need to
get
data from one or more outside sources to send back to your client). Is
this
of interest to anyone?