Is this the best start to ruby socket server for flash clients?

Hello,

My goal is to make the fastest, most stable Ruby persistant socket
server for Flash clients as possible. I’d like it to run on a Windows
2000 server, but if sold on Redhat Linux for this application, then
that’s fine.

How many persistant sockets could this app handle in your experience
as is or with your improvements? Currently it kicks back what gets
sent to it.

The code below is my foundation, how I can make it even better for to
meet the stated goals. Your ideas are encouraged and appreciated.

Thank you,

Rick

require “socket”

listenIp = "0.0.0.0"
listenPort = 1234

socket = TCPServer.new(listenIp,listenPort)
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)

begin
while
thisThread = Thread.new(session = socket.accept) {|thisSession|
while thisSession
# assuming a flash client
fromClient = thisSession.gets("\0")
thisSession.write(fromClient)
# is sleep a good idea, and then awaken when needed?
end
}
end
rescue StandardError => bang
print "show error: " + bang
end

I thought threading in Ruby was not the fastest way… since it doesn’t use
native threads…

-Rich
(aka VAYKENT)

···

----- Original Message -----
From: “Rick” moonerent@yahoo.com
Newsgroups: comp.lang.ruby
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Thursday, October 31, 2002 2:59 AM
Subject: Is this the best start to ruby socket server for flash clients?

Hello,

My goal is to make the fastest, most stable Ruby persistant socket
server for Flash clients as possible. I’d like it to run on a Windows
2000 server, but if sold on Redhat Linux for this application, then
that’s fine.

How many persistant sockets could this app handle in your experience
as is or with your improvements? Currently it kicks back what gets
sent to it.

The code below is my foundation, how I can make it even better for to
meet the stated goals. Your ideas are encouraged and appreciated.

Thank you,

Rick

require “socket”

listenIp = “0.0.0.0”
listenPort = 1234

socket = TCPServer.new(listenIp,listenPort)
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)

begin
while
thisThread = Thread.new(session = socket.accept) {|thisSession|
while thisSession
# assuming a flash client
fromClient = thisSession.gets(“\0”)
thisSession.write(fromClient)
# is sleep a good idea, and then awaken when needed?
end
}
end
rescue StandardError => bang
print "show error: " + bang
end

Rich,

I’m reviewing previous post regarding this point. In the mean time
here’s a new draft for the group to take apart…

require “socket”

@@threadsOpen = ThreadGroup.new
listenIp = "0.0.0.0"
listenPort = 1234

socket = TCPServer.new(listenIp,listenPort)
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)

while
thisThread = Thread.new(session = socket.accept) {|thisSession|
while thisSession
fromClient = thisSession.gets("\0") # assuming a flash client
if fromClient != nil
thisSession.write(fromClient)
#puts (fromClient)
#puts (@@threadsOpen.list)
sleep 1
else
thisSession.close
thisThread.kill
end
end
}
@@threadsOpen.add(thisThread)
end

Hello Rich,

Thursday, October 31, 2002, 7:26:46 PM, you wrote:

I thought threading in Ruby was not the fastest way… since it doesn’t use
native threads…

i thonk opposite - ruby “threads” has less overhead and switched at
least at each elementary ruby operation

···


Best regards,
Bulat mailto:bulatz@integ.ru

Starting a new thread for each incoming connection is not a good idea.
If too many threads get started, the task switching can bog you down.

There are many design choices here.
You can create a set number of threads that all retrieve tasks from a
queue of
tasks.

You can create a thread pool to control the number of threads.

There are various patterns for event dispatching frameworks that
control when
events get executed and how threads are utilized.

I highly recommend Concurrent Programming in Java, Second Edition.
Design Principles and Patterns by Doug Lea.
The focus of the book is in writing well designed Concurrent
applications.
Java is just used for the examples.

You can do everything asynchonously.

You should examine the documentation for Apache. They lay out all
their design choices and why. It has been a couple years since I saw
this, so I can’t say where. I think you can find it from the FAQ.

Thank you much for these your thoughts and direction. I will get the
book and rethink the approach.

In the mean time here’s the latest greatest threaded approach:

It rejects users at 250 sockets on windows 2000 server and 500 sockets
on Redhat linux. This is because “default is limited to 1024 file
descriptors, this is done with proc settings” and each socket takes
two. Looking into how and if this limit should be increased.

require “socket”

@@threadsOpen = ThreadGroup.new
listenIp = "0.0.0.0"
listenPort = 1234

socket = TCPServer.new(listenIp,listenPort)
socket.setsockopt(Socket::SOL_SOCKET, Socket::TCP_NODELAY, true)
#IPPROTO_TCP for windows

while
thisThread = Thread.new(session = socket.accept) {|thisSession|
lastMessage = nil
while thisSession
if thisSession.eof? #test if socket is closed
puts (“session closed”)
thisSession.close
thisThread.kill
else #socket is open
fromClient = thisSession.gets("\0")
if lastMessage != fromClient # avoid repeating previous line
toClient = fromClient
lastMessage = fromClient
else
toClient = "beat\0"
end
thisSession.write(toClient)
puts (toClient)
end
sleep .75
end
}
@@threadsOpen.add(thisThread)
end