# Which server component?

**URL:** <https://www.ruby-forum.com/t/which-server-component/179569>\
**Category:** Ruby\
**Created:** [November 28, 2009, 9:33pm UTC](https://www.ruby-forum.com/t/which-server-component/179569 "2009-11-28T21:33:59Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 28, 2009, 9:33pm UTC](https://www.ruby-forum.com/t/which-server-component/179569/1 "2009-11-28T21:33:59Z")

</div>

Hello!

I have the scenarion, that on the one hand, there are mobile devices  
which are the clients, on the other hand there is a server with ruby.

The clients send the messages to the server witch JSON via a persistent  
TCP connection (it must be persistent). The server (ruby scripts)  
receive the messages and send a JSON answer string back to the client.

My ruby tcp server is build up with this snippet of source code:  
[http://segment7.net/projects/ruby/snippets/server.rb](http://segment7.net/projects/ruby/snippets/server.rb)

Now I like to run it on port 80/443 as a webservice, because the tcp  
server is not so scalable and I do not have any idea how to run it  
secure via ssl/tls.  
WhatÂ´s the best way to do this? The ruby-side ist pure ruby (not rails)  
with gems like Sequel, Validatable, JSON.

Should I use an apache webserver mit Phusion Passenger or there are  
better ways that the server could make persistent tcp connections with  
security (SSL) to send/receive JSON messages?

Thanks a lot in advance & Best Regards.

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 28, 2009, 10:08pm UTC](https://www.ruby-forum.com/t/which-server-component/179569/2 "2009-11-28T22:08:20Z")

</div>

> The clients send the messages to the server witch JSON via a persistent  
> TCP connection (it must be persistent). The server (ruby scripts)  
> receive the messages and send a JSON answer string back to the client.
> 
> My ruby tcp server is build up with this snippet of source code:  
> [http://segment7.net/projects/ruby/snippets/server.rb](http://segment7.net/projects/ruby/snippets/server.rb)
> 
> Now I like to run it on port 80/443 as a webservice, because the tcp  
> server is not so scalable and I do not have any idea how to run it  
> secure via ssl/tls.

You are talking about two different things. Webservers talk HTTP(S). You  
can have a persistent HTTP connection, but the messages sent over it  
would be HTTP requests and responses.

At the moment, you are talking directly over TCP, and your message  
structure is just JSON objects delimited by newline.

So really you have two options:

- scale your existing protocol. You could make it work very efficiently  
with thousands of concurrent connections using ‘eventmachine’ or one of  
the other reactor-pattern libraries. Adding SSL to your existing code is  
also pretty easy.

- or you switch entirely to a new protocol, which would be JSON over  
HTTP(S). This is more heavyweight (higher overhead), but does give you a  
large number of scaling options and is arguably more ‘standard’ than  
your existing custom protocol.

> Should I use an apache webserver mit Phusion Passenger or there are  
> better ways that the server could make persistent tcp connections with  
> security (SSL) to send/receive JSON messages?

As this is a very small service and you want it to run as fast as  
possible, I suggest you write it as a Rack application. There are then  
lots of different ways you can actually run your Rack application (under  
Phusion Passenger is just one of them)

Look at the examples which come with Rack to see how it works, it’s  
extremely simple.  
[http://rack.rubyforge.org/](http://rack.rubyforge.org/)

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 28, 2009, 11:36pm UTC](https://www.ruby-forum.com/t/which-server-component/179569/3 "2009-11-28T23:36:07Z")

</div>

Thank you very much for your reply!

Brian C. wrote:

> > The clients send the messages to the server witch JSON via a persistent  
> > TCP connection (it must be persistent). The server (ruby scripts)  
> > receive the messages and send a JSON answer string back to the client.
> > 
> > My ruby tcp server is build up with this snippet of source code:  
> > [http://segment7.net/projects/ruby/snippets/server.rb](http://segment7.net/projects/ruby/snippets/server.rb)
> > 
> > Now I like to run it on port 80/443 as a webservice, because the tcp  
> > server is not so scalable and I do not have any idea how to run it  
> > secure via ssl/tls.
> 
> You are talking about two different things. Webservers talk HTTP(S). You  
> can have a persistent HTTP connection, but the messages sent over it  
> would be HTTP requests and responses.  
> Okay, I understand what you mean.

> At the moment, you are talking directly over TCP, and your message  
> structure is just JSON objects delimited by newline.  
> Right.

> So really you have two options:
> 
> - scale your existing protocol. You could make it work very efficiently  
> with thousands of concurrent connections using ‘eventmachine’ or one of  
> the other reactor-pattern libraries. Adding SSL to your existing code is  
> also pretty easy.  
> If I would use EventMachine, how would be the architecture? EventMachine  
> receives the messages and forward it to my ruby scripts? But  
> EventMachine would replace my TCP server? And with EventMachine it is  
> easy to set up a persistent SSL connection?

> - or you switch entirely to a new protocol, which would be JSON over  
> HTTP(S). This is more heavyweight (higher overhead), but does give you a  
> large number of scaling options and is arguably more ‘standard’ than  
> your existing custom protocol.  
> Okay.

> > Should I use an apache webserver mit Phusion Passenger or there are  
> > better ways that the server could make persistent tcp connections with  
> > security (SSL) to send/receive JSON messages?
> 
> As this is a very small service and you want it to run as fast as  
> possible, I suggest you write it as a Rack application. There are then  
> lots of different ways you can actually run your Rack application (under  
> Phusion Passenger is just one of them)  
> Okay, I could build up an apache webserver with for example phusion  
> passenger which enables the ssl security and the persistent connection.  
> And then I use Rack to get the requests and I can send the responses  
> back to the client. Is that right? But how do I call the server from the  
> client? Is it a POST HTTP Request with the JSON message in his body?

> Look at the examples which come with Rack to see how it works, it’s  
> extremely simple.  
> [http://rack.rubyforge.org/](http://rack.rubyforge.org/)  
> Ruby on Rails did also use this? I have to read a little bit…  
> Thanks a lot!

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 29, 2009, 11:37am UTC](https://www.ruby-forum.com/t/which-server-component/179569/4 "2009-11-29T11:37:53Z")

</div>

Tim Bennen wrote:

> > - scale your existing protocol. You could make it work very efficiently  
> > with thousands of concurrent connections using ‘eventmachine’ or one of  
> > the other reactor-pattern libraries. Adding SSL to your existing code is  
> > also pretty easy.  
> > If I would use EventMachine, how would be the architecture? EventMachine  
> > receives the messages and forward it to my ruby scripts? But  
> > EventMachine would replace my TCP server?

Yes, eventmachine would replace your TCP server. You would have to rejig  
your application into an event-handling model, rather than a threaded  
model. Because there are no threads, it scales very well.

I’m assuming here that the scaling you’re looking for is large numbers  
of concurrent TCP connections, more than large numbers of messages per  
second. But you can also scale to multiple cores and/or servers by  
putting a simple TCP load balancer in front of your server(s). ‘pen’ is  
a suitable software load-balancer, or you can buy lots of different  
hardware appliances.

> And with EventMachine it is  
> easy to set up a persistent SSL connection?

I’m not sure, you’d have to look for samples in the eventmachine  
distribution and/or ask on an EventMachine list. But I would strongly  
expect it has been done before.

With a simple TCP socket server like you already have, it’s easy to turn  
it into an SSL server. For example, there is code in ruby-ldapserver  
which does this (look at startssl in connection.rb and ssl\_prepare in  
server.rb)

> Okay, I could build up an apache webserver with for example phusion  
> passenger which enables the ssl security and the persistent connection.  
> And then I use Rack to get the requests and I can send the responses  
> back to the client. Is that right?

Yes. And for initial testing, you can run the rack app directly under  
mongrel or thin or even webrick (rackup will start these servers for  
you)

> But how do I call the server from the  
> client? Is it a POST HTTP Request with the JSON message in his body?

Yes. And you’d send back an application/json response with the JSON  
message in the body.

Note that HTTP limits you to exactly one response per request. That is,  
the server can’t send back asynchronous unsolicited responses to the  
client. If you want to do that with HTTP, you’d have to get the client  
to send a request and block waiting for a response (aka ‘COMET’) or poll  
periodically.

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 29, 2009, 2:01pm UTC](https://www.ruby-forum.com/t/which-server-component/179569/5 "2009-11-29T14:01:07Z")

</div>

Tim Bennen wrote:

> > Yes. And for initial testing, you can run the rack app directly under  
> > mongrel or thin or even webrick (rackup will start these servers for  
> > you)  
> > Okay, I read: "One popular configuration is to run Apache 2.2 as a load  
> > balancer using mod\_proxy\_balancer in conjunction with several Mongrel  
> > instances,  
> > …

Ignore that. Write your application as a rack application (just a single  
Ruby object with a ‘call’ method). Then test it using the built-in  
mongrel/thin/webrick handler. When you’re happy with it, _then_ look at  
ways of deploying a rack application. At the moment, Phusion Passenger  
(under either apache or nginx) and Unicorn (under nginx) look like good  
options and both are much simpler than messing around with multiple  
application instances started manually and bound to different ports.

> > Note that HTTP limits you to exactly one response per request. That is,  
> > the server can’t send back asynchronous unsolicited responses to the  
> > client. If you want to do that with HTTP, you’d have to get the client  
> > to send a request and block waiting for a response (aka ‘COMET’) or poll  
> > periodically.  
> > Does that mean, the client establish a connection and only(!) if the  
> > client requests something, there will be one response from the server?  
> > So, it is not possible that the server send a message without(!) a  
> > request from the client?

Correct. So the client must send a request GET /messages (say). If the  
server responds immediately with ‘no message available’ then the client  
must poll periodically. If the server blocks and doesn’t send a response  
until there is one, then you get COMET. If you’re running COMET with  
something like Apache or nginx in front, you need to beware that they  
may time out idle connections, there may be some tweaking to do.

Or you can use a hybrid approach: poll, block for up to 2 minutes (say),  
then reply with a message or ‘no message available’.

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 29, 2009, 1:20pm UTC](https://www.ruby-forum.com/t/which-server-component/179569/6 "2009-11-29T13:20:31Z")

</div>

> I’m assuming here that the scaling you’re looking for is large numbers  
> of concurrent TCP connections, more than large numbers of messages per  
> second.  
> Yes, thatÂ´s right!

> But you can also scale to multiple cores and/or servers by  
> putting a simple TCP load balancer in front of your server(s). ‘pen’ is  
> a suitable software load-balancer, or you can buy lots of different  
> hardware appliances.  
> Okay, but this seems to me not to be the “standard way”. It would be  
> better if I will use standard technologies, so other people could easily  
> maintain it, like an Apache webserver. But this is a good alternative!

> > And with EventMachine it is easy to set up a persistent SSL connection?  
> > I’m not sure, you’d have to look for samples in the eventmachine  
> > distribution and/or ask on an EventMachine list. But I would strongly  
> > expect it has been done before.  
> > Okay, I will look.

> With a simple TCP socket server like you already have, it’s easy to turn  
> it into an SSL server. For example, there is code in ruby-ldapserver  
> which does this (look at startssl in connection.rb and ssl\_prepare in  
> server.rb)  
> That seems easy, easier than expected. That’s all? Only 10-15 lines of  
> code to establish a SSl connection? Wow.

> > Okay, I could build up an apache webserver with for example phusion  
> > passenger which enables the ssl security and the persistent connection.  
> > And then I use Rack to get the requests and I can send the responses  
> > back to the client. Is that right?
> 
> Yes. And for initial testing, you can run the rack app directly under  
> mongrel or thin or even webrick (rackup will start these servers for  
> you)  
> Okay, I read: "One popular configuration is to run Apache 2.2 as a load  
> balancer using mod\_proxy\_balancer in conjunction with several Mongrel  
> instances, with each Mongrel instance running on a separate port. This  
> is something that can be configured very easily using the  
> mongrel\_cluster management utility. Apache can divide the incoming  
> requests among the available Mongrel processes, and, with careful  
> configuration, can even serve static content itself without having to  
> delegate to Mongrel.

For those who wish to avoid Apache altogether, it is possible to deploy  
a Mongrel cluster with an alternative web server, such as nginx or  
lighttpd, and a load balancer of some variety such as Pound or a  
hardware-based solution." (wikipedia)

Do you think that is a good idea to do this?  
Perhaps I will build up an Apache webserver with one Mongrel webserver  
with Rack and my ruby scripts on one hardware server. This must be  
possible?!  
If I will need more webserver, then I buy a new hardware server, install  
mongrel with my application and that’s fine. But isn’t it a problem with  
the database if I only have one database and several webserver which  
connect/read/write?

> > But how do I call the server from the  
> > client? Is it a POST HTTP Request with the JSON message in his body?
> 
> Yes. And you’d send back an application/json response with the JSON  
> message in the body.  
> Okay, that would be perfect.

> Note that HTTP limits you to exactly one response per request. That is,  
> the server can’t send back asynchronous unsolicited responses to the  
> client. If you want to do that with HTTP, you’d have to get the client  
> to send a request and block waiting for a response (aka ‘COMET’) or poll  
> periodically.  
> Does that mean, the client establish a connection and only(!) if the  
> client requests something, there will be one response from the server?  
> So, it is not possible that the server send a message without(!) a  
> request from the client?

Thanks a lot and best regards!

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 29, 2009, 6:12pm UTC](https://www.ruby-forum.com/t/which-server-component/179569/7 "2009-11-29T18:12:18Z")

</div>

> > > Yes. And for initial testing, you can run the rack app directly under  
> > > mongrel or thin or even webrick (rackup will start these servers for  
> > > you)  
> > > Okay, I read: "One popular configuration is to run Apache 2.2 as a load  
> > > balancer using mod\_proxy\_balancer in conjunction with several Mongrel  
> > > instances,  
> > > …
> 
> Ignore that. Write your application as a rack application (just a single  
> Ruby object with a ‘call’ method). Then test it using the built-in  
> mongrel/thin/webrick handler. When you’re happy with it, _then_ look at  
> ways of deploying a rack application. At the moment, Phusion Passenger  
> (under either apache or nginx) and Unicorn (under nginx) look like good  
> options and both are much simpler than messing around with multiple  
> application instances started manually and bound to different ports.  
> Okay, I will do it that way. But I should prepare the load balancing, so  
> I think I will use one apache as a load balancer and one mongrel/rack  
> combination. Is the Mongrel webserver included into Rack? I don’t think  
> so, only the “gateway” between a Mongrel and Rack?

> > > Note that HTTP limits you to exactly one response per request. That is,  
> > > the server can’t send back asynchronous unsolicited responses to the  
> > > client. If you want to do that with HTTP, you’d have to get the client  
> > > to send a request and block waiting for a response (aka ‘COMET’) or poll  
> > > periodically.  
> > > Does that mean, the client establish a connection and only(!) if the  
> > > client requests something, there will be one response from the server?  
> > > So, it is not possible that the server send a message without(!) a  
> > > request from the client?
> 
> Correct. So the client must send a request GET /messages (say). If the  
> server responds immediately with ‘no message available’ then the client  
> must poll periodically. If the server blocks and doesn’t send a response  
> until there is one, then you get COMET. If you’re running COMET with  
> something like Apache or nginx in front, you need to beware that they  
> may time out idle connections, there may be some tweaking to do.  
> Hm, that’s a problem, because if something happened on the server, and  
> the user should be notified, I have to poll every 2-3 seconds and that’s  
> a lot of data, because the clients could be mobile devices and that’s  
> expensive.  
> Is there a Ruby Comet implementation?

> Or you can use a hybrid approach: poll, block for up to 2 minutes (say),  
> then reply with a message or ‘no message available’.  
> Okay, thatÂ´s also a possible solution…

Using Rack/Mongrel or Apache/Mongrel/Rack the connection could be  
established as persistent?

Thanks a lot! Regards.

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 29, 2009, 7:15pm UTC](https://www.ruby-forum.com/t/which-server-component/179569/8 "2009-11-29T19:15:47Z")

</div>

Robert K. wrote:

> In that case it sounds like as if HTTP was not the ideal protocol for  
> the task. Maybe you should rather follow the other direction and think  
> about a solution with EventMachine as Brian has sketched.

Another option is to use XMPP (aka Jabber). This is asynchronous and  
there are a variety of implementations to choose from. If you want  
something that scales to tens of thousands of connections, look at  
ejabberd. Even though that’s written in erlang, you could still sit it  
in between a large pool of clients and a server written in ruby +  
xmpp4r.

---

<div class="post-metadata">

**Author:** ![tbobker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/73ab20/32.png) [@tbobker](https://www.ruby-forum.com/u/tbobker)\
**Post date:** [November 29, 2009, 6:55pm UTC](https://www.ruby-forum.com/t/which-server-component/179569/9 "2009-11-29T18:55:51Z")

</div>

On 11/29/2009 06:12 PM, Tim Bennen wrote:

> > Correct. So the client must send a request GET /messages (say). If the  
> > server responds immediately with ‘no message available’ then the client  
> > must poll periodically. If the server blocks and doesn’t send a response  
> > until there is one, then you get COMET. If you’re running COMET with  
> > something like Apache or nginx in front, you need to beware that they  
> > may time out idle connections, there may be some tweaking to do.  
> > Hm, that’s a problem, because if something happened on the server, and  
> > the user should be notified, I have to poll every 2-3 seconds and that’s  
> > a lot of data, because the clients could be mobile devices and that’s  
> > expensive.

In that case it sounds like as if HTTP was not the ideal protocol for  
the task. Maybe you should rather follow the other direction and think  
about a solution with EventMachine as Brian has sketched. That way you  
can also have better control over the protocol overhead - HTTP can be  
quite verbose if your messages are really small (say 50 bytes or so):  
the ratio of payload to protocol wouldn’t be too good in that case.

> Using Rack/Mongrel or Apache/Mongrel/Rack the connection could be  
> established as persistent?

AFAIK with HTTP even if the client indicates he wants to stay connected  
the server is free to drop the connection if he feels like it (e.g.  
running low on open file descriptors, too much idle time etc. Brian  
hinted in the same direction). That, too, seems like a reason to look  
at something other than HTTP. My 0.02 EUR anyway.

Kind regards

robert
