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
···
--
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.
Ok that was one stupid wtf....
i forgot to put "\n" in the end of the string, i guess.
···
On 9/19/06, hemant <gethemant@gmail.com> 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.
--
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.
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.
···
On 9/19/06, hemant <gethemant@gmail.com> 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.
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, Francis Cianfrocca <garbagecat10@gmail.com> wrote:
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.
--
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.
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?
···
On 9/19/06, hemant <gethemant@gmail.com> 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?
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.