Hello, I need to write a client/server application and I'd like to some advice from more experienced users. There will be multiple clients and one server. Every client should automatically identify to the server and give some details (client_id, date, time, etc). The identification needs to be at very basic level, just to avoid *strange things* from happening, since the server is going to listen on the internet (firewall rules will be applied, but some clients may have dynamic ip's, so some subnets might be able to connect). The server will dig for data from a database, at each client's request will send an array (list of words) to the client. Then the server will receive a hash with detailed info from the client about the each element of the array and will dump the results into the database. These arrays will be formed only when requested by clients. The server will make sure clients don't get the same arrays and make a check to the given results and that's about it. It's a fairly simple application. I was thinking of using sinatra + routes, to create the list in 'txt' format to the client but I'm not sure how to send the results back to the sinatra server yet. So I'd like to ask more advanced users if there's any protocol, gem and/or framework that would make this task easier since I've never done anything similar before. I know there's a variety of protocols which can be used. I'd like to keep things simple & clean as much as possible. Thanks for your time Panagiotis (atmosx) Atmatzidis email: atma@convalesco.org URL: http://www.convalesco.org GnuPG ID: 0xE736C6A0 gpg --keyserver x-hkp://pgp.mit.edu --recv-keys 0xE736C6A0
on 2012-11-17 22:10
on 2012-11-18 00:14
On 18/11/2012, at 10:09 AM, Panagiotis Atmatzidis wrote:
> So I'd like to ask more advanced users if there's any protocol, gem and/or
framework that would make this task easier since I've never done anything similar
before. I know there's a variety of protocols which can be used. I'd like to keep
things simple & clean as much as possible.
http is your friend
Henry
on 2012-11-18 09:05
Subject: Advice for simple client/server application Date: Sun 18 Nov 12 06:09:42AM +0900 Quoting Panagiotis Atmatzidis (atma@convalesco.org): > > sure how to send the results back to the sinatra server yet. > > So I'd like to ask more advanced users if there's any protocol, gem > and/or framework that would make this task easier since I've never > done anything similar before. I know there's a variety of protocols > which can be used. I'd like to keep things simple & clean as much as > possible. You do not specify if the clients are also written in Ruby. When I have to do inter-process communications, on the same machine or between remote machines, I use DRb (Distributed Ruby), which is included in MRI. I certainly had to pour some sweat to gain confidence with it, but it was worth the effort. You can even set it up to use SSL, so the traffic will be encrypted. Let's say you have a server based on this scaffold (engine.rb): --8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- require 'drb/drb' require 'drb/ssl' class Engine HOST='yourhost.xxx' PORT=21212 URI="drbssl://#{HOST}:#{PORT}" CERTNAME=[['C',HOST.split('.')[-1]],['O',HOST],['CN',self.to_s]] def initialize config={:verbose=>false,:SSLCertName=>CERTNAME} @srv=DRb::start_service(URI,self,config) # # Your inits # @para1=rand(1000) @para2=rand(1000) end def runme DRb::thread.join() end # # Remote-callable methdos # def method1(a) "#{@para1} #{@para2} method 1 returns #{a.to_s}" end def method2(a) "#{@para1} #{@para2} method 2 returns #{a.to_s} #{a.to_s}" end def Engine::remote config={:verbose=>false} DRb.start_service(nil,nil,config) DRbObject.new(nil,URI) end end if($0==__FILE__) Engine::new.runme end --8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- Your client may be something like this: --8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- require 'engine.rb' class Client def initialize @engine=Engine::remote end def runme puts @engine.method1(rand(1000)) puts @engine.method1('test') puts @engine.method2(rand(1000)) puts @engine.method2('test') end end Client::new.runme --8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- Your engine can provide an identify method (you may have a hash of user ids/passwords associated to one or more address, for example). Then, you would have a 'dig' method that would provide the desired list of words. For me, DRb has cut the cake several times (you can also base it on Unix sockets, for intra-machine communications). There are some snags. The biggest is that methods of the DRb-exported objects are executed remotely, but if your client receives remote objects, it will receive LOCAL COPIES of them. Let's say your engine has object @ob, which has method meth. If your engine has this method def m @ob.meth end meth is executed remotely, by the engine process. But if your methods just returns @ob: def m @ob end and in your client you have ob=@engine.m ob.meth meth is executed in the client's thread (and thus, for example, it won't be able to access the database opened by the remote engine). I hope this is of help. Carlo
on 2012-11-18 11:45
Hello, On 18 Νοε 2012, at 09:04 , Carlo E. Prelz <fluido@fluido.as> wrote: >> (client_id, date, time, etc). The identification needs to be at very >> clients. The server will make sure clients don't get the same arrays >> possible. > --8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<-- > config={:verbose=>false,:SSLCertName=>CERTNAME} > def runme > > end > > end > For me, DRb has cut the cake several times (you can also base it on > > ob.meth > * K * Carlo E. Prelz - fluido@fluido.as che bisogno ci sarebbe > * di parlare tanto di amore e di rettitudine? (Chuang-Tzu) > Thanks for code sample and the extensive answer Carlo! So from what I understand, druby opens a connection and keeps it alive until the client ends execution right? This approach could be a solution, thanks :-) Panagiotis (atmosx) Atmatzidis email: atma@convalesco.org URL: http://www.convalesco.org GnuPG ID: 0xE736C6A0 gpg --keyserver x-hkp://pgp.mit.edu --recv-keys 0xE736C6A0
on 2012-11-19 09:46
Subject: Re: Advice for simple client/server application Date: Sun 18 Nov 12 07:44:15PM +0900 Quoting Panagiotis Atmatzidis (atma@convalesco.org): > So from what I understand, druby opens a connection and keeps it > alive until the client ends execution right? From what I can see, Connection is closed either at end of the script execution, or when the DRb instance is garbage-collected. There may exist an explicit way to close a link without destroying the object, but I have never needed such a thing. I would not keep idle links open for long times. I'd either open a new instance each time I need it, or maybe send keep-alive pings at regular intervals. It really depends on the type of the application. Carlo
on 2012-12-24 18:20
Carlo, I came from a link(http://www.ruby-forum.com/topic/4409293#1090107) to this. Seems that first I need to fully understand how a client-server communication work, I've never experienced with it. Can you recomend any material to read or something? or do you think that simply learning DRb plus trial and error is sufficient? what will be less painfull?
on 2012-12-24 19:16
Subject: Re: Advice for simple client/server application Date: Tue 25 Dec 12 02:20:48AM +0900 Quoting Dami??n M. Gonz??lez (lists@ruby-forum.com): > Carlo, I came from a > link(http://www.ruby-forum.com/topic/4409293#1090107) to this. Seems > that first I need to fully understand how a client-server communication > work, I've never experienced with it. Can you recomend any material to > read or something? or do you think that simply learning DRb plus trial > and error is sufficient? what will be less painfull? The amount of increased understanding is directly proportional to the amount of suffering involved ;-) My personal experience of inter-process-communications is that of: 1) talking between applications on a 300baud phone line... 2) Using SystemV IPC 3) chatting between unix sockets 4) reading a bit about CoRBA and being disgusted about that committee-smacking stuff (I still have a book somewhere: anybody wants to buy it?) 5) seeing the light with DRb. Basically, with 1-3 you just send and receive bytes: you must create and enforce your own more-or-less high-level protocols. 4 and 5 (as well as a myriad of other more or less successful solutions that I was spared), on the other hand, are object-oriented inter-process communications. CoRBA pretended to be language-independent, and an awkward crock was the result. DRb, on the other hand, is Ruby-only (and made in Japan ;-), so it is clean and straightforward. I do not have tutorials to suggest, since I generally learn by doing. But the nutshell is simple: from a process running here on my PC I can invoke the methods of an object instantiated by a process running in a toaster plugged to the internet in Waikaki, New Zealand, in a transparent way. It is *almost* as if the two processes were the same. The scope of the *almost* will only become clear to you with experience. Carlo
on 2012-12-25 17:11
On Mon, Dec 24, 2012 at 7:15 PM, Carlo E. Prelz <fluido@fluido.as> wrote: > Subject: Re: Advice for simple client/server application > Date: Tue 25 Dec 12 02:20:48AM +0900 > The amount of increased understanding is directly proportional to the > amount of suffering involved ;-) :-) > My personal experience of inter-process-communications is that of: > > 4) reading a bit about CoRBA and being disgusted about that > committee-smacking stuff (I still have a book somewhere: anybody > wants to buy it?) > 4 and 5 (as well as a myriad of other more or less successful > solutions that I was spared), on the other hand, are object-oriented > inter-process communications. > > CoRBA pretended to be language-independent, and an awkward crock was > the result. Sorry, I have to intervene here: CORBA does not deserve such a bad reputation. It *is* language independent which naturally introduces some level of complexity. But, for example, IIOP is pretty well done since it especially allows for small message sizes - much smaller than what is needed for a WebService SOAP request and response. For WAN communication this is an advantage. > DRb, on the other hand, is Ruby-only (and made in Japan > ;-), so it is clean and straightforward. Well, to be fair it was written against a different set of requirements. Especially the fact that no support for different programming languages was needed made things significantly easier. Plus, of course, the elegance of Ruby helped a lot in making DRb easy to use and blend seamlessly with local functionality. > I do not have tutorials to suggest, since I generally learn by > doing. But the nutshell is simple: from a process running here on my > PC I can invoke the methods of an object instantiated by a process > running in a toaster plugged to the internet in Waikaki, New Zealand, > in a transparent way. I'd *love* to see a picture of that toaster. :-) > It is *almost* as if the two processes were the > same. The scope of the *almost* will only become clear to you with > experience. Basically the central question for distributed applications is: which data is stored where and what do I need to transfer between processes. Since remote method calls are much more expensive than in process method calls people typically focus on reducing the number or frequency of remote calls at the expense of more data being sent with a single invocation. Kind regards robert
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.