|
|
Comments and Discussions
|
|
 |

|
if (length > 1024*10) // 10K limit on message sizes, for now
connections.cpp line 374
Why? can i commnet this?
Thanks
|
|
|
|

|
I'm not thinking so, but is it possible to pass abstract classes to a method of an RCF-exposed object? For example, say I have the following class whose doIt() method is exposed via RCF:
class RemoteClass
{
public:
RemoteClass();
virtual ~RemoteClass();
void doIt(AbstractThing* thing);
};
In this case, AbstractThing is defined as follows:
class AbstractThing
{
public:
AbstractThing();
virtual ~AbstractThing();
virtual void neatMethod() = 0;
};
As you can see, it's an abstract class because its neatMethod() is pure virtual. Now assuming that a client tries to call the doIt() method of RemoteClass, passing in a subclass of AbstractThing, what will happen? For example, assume the subclass of AbstractThing is defined as:
class Something : public AbstractThing
{
public:
Something();
virtual ~Something();
void neatMethod();
};
and the client does this:
Something thing;
RcfClient<RemoteClass> client("localhost", 10000);
client.doIt(&thing);
what will happen?
ScoPi
|
|
|
|

|
How can I use RCF with multiple instaces of Specific Object?
class Obj{
void XXX(){}
};
main()
{
Obj ob1,ob2;
//????Bind????///
}
Thanks
|
|
|
|

|
Hi,
As I said before, I use your framework for network communication and everything is
working as it should.
Yet now I need to save the data that is serialized/deserialized through the network
to a file and read it back at a later time (for diagnostics purposes).
I thought to use std::fstream (ifstream and ofstream) as you have in the SF framework
the classes SF::IBinaryStream and SF::OBinaryStream which uses std::istream and std::ostream.
Since ifstream et ofstream derives from those, I thought it would work right away. Yet,
I can write to file but I cannot read it back.
Is there something special to do ? Here is a code snippet that illustrates what I do...
// Save function
// other stuff before
std::ofstream out_file(strFileName, std::ios::out);
SF::OBinaryStream out_stream(out_file);
try
{
out_stream << tempPlanche.m_plancheOpt;
}
catch(SF::Exception ex)
{
AfxMessageBox(ex.what());
}
catch(...)
{
// handle error...
}
out_file.flush();
out_file.close();
// Load function (in another part of the code where it is needed)
CPlanche planche;
std::ifstream in_file(vFiles[lFile].c_str(), std::ios::in);
SF::IBinaryStream in_stream(in_file);
try
{
in_stream >> planche;
pDoc->JouePlanche(planche);
}
catch(SF::Exception ex)
{
AfxMessageBox(ex.what());
}
catch(...)
{
// Handle error
}
in_file.close();
Is there something wrong in this ? I can't see what it could be, even with looking at Test_Serialization.cpp.
The error I get from SF::Exception is has follows :
e:\projets\commun\rcf\src\stream.cpp(307): unsigned long __thiscall SF::IStream::read(char*, unsigned long): : Thread-id=4604 :
Timestamp(ms)=19296: THROW: Exception: fail bit set on std::istream: nLength=1, is.gcount()=0,
thanks for any input.
Alexandre Senechal, ing. jr
Programmer
Optifor inc.
|
|
|
|

|
Using Visual Studio .NET 2003 (7.1?), I am getting the following compilation error:
C:\src\RCF\include\RCF\ServerStub.inl(20): error C2668: 'RcfClient::invoke' : ambiguous call to overloaded function
Any ideas?
ScoPi
|
|
|
|

|
Hi,
I upgraded your Framework for my project to the 2005-10-19 version and since I am
having trouble with my software. I found out that the problem is the throw that follows in the
RCF/Connection.cpp file. I did not check any other files for this neither as most of the times
the throw came from there.
382: Reorder()(&length, sizeof(length), 1);
383: if (length > 1024*10) // 10K limit on message sizes, for now
384: {
385: RCF_THROW(RecvException, "too much data")(fd)(length);
386: }
387: std::vector vec(length);
388: ret = recv(timeout, fd, &vec[0], length, 0);
389: if (ret == length)
Compared to the 2005-03-10 version, which I was using without problems up-to recently,
372: Reorder()(&length, sizeof(length), 1);
373: std::vector vec(length);
374: ret = recv(timeout, fd, &vec[0], length, 0);
375: if (ret == length)
which does not have this limitation. Why did you add such a limitation ?
The thing is my data is at least the double of your limit size (about 20K) and we made
some tests with the 2005-03-10 version with data much bigger than this without any problems ?
For 20K we had transfer times of 4 ms on wire... that is quite good and it was not degrading too
much as the data size increased. Anyway, I know I can just remove that limitation, but I am really
wondering what is the reason behind it ?
thanks
Alexandre Senechal, ing. jr
Programmer
Optifor inc.
|
|
|
|

|
Hello,
I am happy to see that RCF is growing in feature and usability.
It is possible to see RCF integrated in boost in the next?
I hope so.
I am testing some routines and I think that RCF will be the core of message and command dispatching on a robotic platform that I am working on ..
So, the question.
I need to send unsigned char (bytes) over a channel, but I see that unsigned char is not natively serialized in RCF/boost ...
As the informations are basically byte arrays, I think that there is already a method to deal with such structures. But at the moment the reading of the tests is quite diffficukt to me.
Have you got some tip on hoe to solve that?
Regards
|
|
|
|

|
Hi, Jarl,
I finally have a few numbers to report that compare
Boost.serialization and Ebenezer Enterprises
approaches. I built two parallel executables using
gcc 4.0.2 that send/serialize a std::list that has
500 ints. In non-optimized executables I found
that our approach took around .23 times as long as
the Boost version. Adding -O3 to the building,
resulted in our approach taking .37 times as long as
the Boost version. (Do you remember if the
performance tests you did used optimization?) Also,
with the optimized build, the Boost executable was 5.8
times larger than the Ebenezer Enterprises executable.
Here is a table that summarizes things.
Approach non-optimized optimized exe size
--------------------------------------------------
Boost 2415 671 74264 bytes
Ebenezer 565 250 12672 bytes
The times are in microseconds and are averages of
multiple runs.
I hope to do further tests that will include user defined
types and more involved messages. If anyone wants to
have the source code I used for the tests let me know.
Brian
www.webEbenezer.net
|
|
|
|

|
Greetings! Your library is very good, but I want to make some changes. I want to abstract out of transport methods for I could write my own transport methods. For example I want to use Naped Pipes. Could you tell me, what classes should I recode on my own without breaking down the library infrastructure ??
Best regards, Vladimir
|
|
|
|

|
Hi,
I justed wanted to let you know, that we succesfully built and used
RCF on QNX 6.3.0, gcc 3.3.1, without too much trouble. Only a matter of defines.
The most difficult part was getting boost to configure correctly, but that
is another story. Your code works on QNX 6.3.0 with gcc 3.3.1 and I tought
you'd like to know.
Have a nice day
Alexandre Senechal, ing. jr
Programmer
Optifor inc.
|
|
|
|

|
First of all, this is good topic. I agree that RPC, CORBA or RMI are all too complicated, but .Net has provided a reasonally simple remoting solution for developers. If we are writing new code on .Net, I don't see why we should build a custom RMI.
With regard to reusing old unmanaged code, it would be a different story. It is worth exploring how we can easily distribute legacy unmanaged objects. There are a number of options. First, COM appears to be #1 choice recommended by many developers. Second, some like to write their own remoting based on sockets. I think your try falls into this category. But they both require significant rework on the old code. Third, .Net has provided another alternative, Interop, which means in our case mixing unmanaged objects with managed remoting. One problem is that the managed remoting cannot marshall unmanaged objects. You may have to write a managed wrapper class for each unmanaged class. This is going to be ugly and eventually similar to the COM approach.
Any comments/suggestions?
|
|
|
|

|
This library is awesome!
Anyway, got this error while compiling against boost 1.33:
Test_StubSerialization.cpp
C:\Programmi\Boost\boost\serialization\is_abstract.hpp(32) : error C2039: 'type' : is not a member of 'boost::
and others ... I can send you the datailed report if necessary ...
Thanks for the nice work!
Andrea Carbone
|
|
|
|

|
I have an enum power { on, off }; Is there any way to serialize this? When I try to call the function RCF_METHOD_R0(power, togglePower); I get compile-time errors about request for member `serialize' in `t', which is of non-class type `power' So RCF is assuming my enum is a class or struct, which is not, therefore it has no member functions, therefore it has no member function serialize(). But enums are just disguised ints. Is there any way to trick RCF into serializing enums as ints, or to override serialize() for a non-class type? Thanks in advance for your help, TheCoderator
|
|
|
|

|
argh. I have these test programs, client and serv. Here is the code: serv.cpp #include <RCF/RCF.hpp> #include <windows.h> #include <iostream> #include <string> using namespace std; using namespace RCF; RCF_BEGIN(I_Chat, "I_Chat") RCF_METHOD_V1(void, print, const string&); RCF_END(I_Chat); class Chat { public: string print(const string &msg) { cout << msg << endl; if (msg == "quit") { cout << "bye" << endl; SetEvent(hEvent); } } static HANDLE hEvent; }; HANDLE Chat::hEvent = NULL; int main() { RcfServer server(50001); server.bind<I_Chat, Chat>(); Chat::hEvent = CreateEvent(NULL, true, false, NULL); server.start(false); WaitForSingleObject(Chat::hEvent, 10000); server.stop(); CloseHandle(Chat::hEvent); return 0; } client.cpp #include <RCF/RCF.hpp> #include <iostream> #include <string> using namespace std; using namespace RCF; RCF_BEGIN(I_Chat, "I_Chat") RCF_METHOD_V1(void, print, const string&); RCF_END(I_Chat); int main() { RcfClient<I_Chat> remote("localhost", 50001); string msg = ""; while (msg != "quit") { getline(cin, msg); remote.print(msg); } return 0; } Basically, the client is supposed to make the server print out whatever is typed in until what is typed in is "quit". Then it is the server's job to shut itself down. This is the part that doesn't work. I peeked in the code and discovered that RcfServer::start(false) isn't supposed to wait for anything, so I thought I could use it and implement my own event. I get the "bye" message, but then either the event doesn't get correctly signaled or I called WaitForSingleObject wrong or it's a thread problem or something. In addition, it doesn't time out after 10 seconds as it should, so the falase I passed to RcfServer::start() isn't working as I expected. Can you help me out here? Thanks -- modified at 15:47 Thursday 6th October, 2005
|
|
|
|

|
This looks great but it won't compile for me.
I copied your sample codee into two projects (I use Dev-C++, which is a frontend for MINGW) and also included RCF/RCF.cpp in both projects.
I get two compile-time errors:
212 p:\c++\rcf\include\RCF\RcfServer.hpp `bind' is not a member of `boost'
212 p:\c++\rcf\include\RCF\RcfServer.hpp `_1' undeclared (first use this function)
I looked at RcfServer.hpp and thought I saw the problem: you had not included . On the offchance it might help, I added that line to the top of the file. But that just causes uncountable Linker Errors when I try to compile my project. I have linked to ws2_32.lib and I downloaded boost and set the include paths, but have not been able to figure out how to compile the libraries.
I really want to use this framework, so please help me make it work!
|
|
|
|

|
This may be a silly question, but where can I find details about the license and/or terms of use for RCF? There is nothing explicitly mentioned in the source distribution, and if I decide to use RCF instead of CORBA for a project, I want to be sure that everything is above board. Thanks.
-Patrick
|
|
|
|

|
Is boost library is a must for building a project? I was trying to add the RCF_NO_BOOST_SERIALIZATION but I have compelation errors.
Thx
Eyal
|
|
|
|

|
Hello.
It is very interesting class.
I have two questions :
1.) Compilation
I just have Visual 6.0.
Will you make sometime the project for this compiler ?
if not, do you think your source code will work well with a visual 6 compilation ?
2.) Send files
My project (EAI) needs to exchange a lot of Xml files. The size of this files can be a big (like 2 mega bytes).
Do you thing if I use your class, I can exchange this "Ascii files" this a string variable (or CString) ?
Thanks for your answers.
(sorry for my poor english !)
Philippe.
|
|
|
|

|
Hello,
is there any chance to handle the clients by username and password instead of allowed ip's? - And find out which client called the function. I want to use different users on a server and not all should have the same permissions to execute all functions.
bye,
Christoph
Goodbye and thanks for the fish!
|
|
|
|
|

|
Hi Jarl,
Hi Jarl,
This framework is absolutely fantastic. I would definately
rate this as 5.
I had couple of question(s):
1. Can I shutdown the server by making a specific
remote-function call from the client.
2. If I want to use your serialization protocol
how do I change the protocol numbers. I had
trouble finding the file that has those
entries.
3. For processes on the same machine can I integrate
named pipes for communicating between processes.
Thank you,
Nitin Motgi
|
|
|
|

|
Hi Jarl,
I am very much interested in your framework and was
trying to understand how the whole thing was written.
Do you have any supporting documents that you can
provide or guide me thru this. Because the way it's
been written is drawing a lot of curiousity. So if
you can provide some pointers or documentation that
would be a lot of help.
Thank you,
Nitin
|
|
|
|

|
I'm using RCF quite intensively. Using Microsoft VC++ 7.1 I sometimes encounter the error C1204 (compiler limit : internal structure overflow). Clearly RCF is not the only cause, but seems to have some responsabilities (the problem has appeared when I introduced RCF into the project; similar projects without RCF do not raise this error). Sometimes I had to pay more attentions to limit the number of includes (so, let's say the error had a positive side effect), but in other cases the only solution I found was to split the cpp file into simpler ones. One class per file was not enough in some cases.
Did you ever encounter similar problems? Or do you have any compile-time switches (defines) that might help in some way?
Currently, the project that raises the issue uses 8 RCF interfaces with 10 to 20 methods for each.
Anyway, besides this error which is a bit boring, I'm still very happy with the framework.
Paolo
|
|
|
|

|
>Performance, as measured in requests/second, is highly dependent on the >serialization protocol, and also on the compiler being used. Before turning to >Boost.Serialization, I used a serialization framework of my own, with which I >could clock around 3000 minimal requests/sec. using Visual C++ 7.1, and 3300 >requests/sec. with Codewarrior 9.0, on a loopback connection on a 1400Mhz, >384Mb PC running Windows XP. GCC 3.2, on the other hand, was far slower. Using >Boost.Serialization, however, I've been nowhere near these numbers; on average, >it's around five times slower.
Have you tried using either www.s11n.net or www.webEbenezer.net
as the serialization framework? I would like to find someone
who isn't working on Boost serialization, s11n.net or
webEbenezer.net that would be interested in comparing the
three.
Brian
|
|
|
|

|
Hello.
It is very interesting library.
I like to extend lib with other data delivery chanels type. Pipes, shared memory, etc. What is the way ? Thank you.
Andrey.
|
|
|
|

|
Here is something very similar that I wrote a couple of years ago.
My motivations were pretty similar, and I was no fan of SOAP either!
http://www.bugbrowser.com/marshal_getting_started.htm
(web site only works properly in IE - sorry)
There was a C/C++ Users Journal article on it - July 2004.
Take a read - it might give you a few ideas - or maybe not
I provided plugable encoders and decoders.
I provided plugable transports, e.g. raw tcp/ip http pipes etc.
There is a live server that you can reach over the Internet http://www.bugbrowser.com/marshal_live_server.htm
with a demo program to call it.
What you've got here looks great, and it's been tested on more compilers than I tested my marshal:: library (I only used VC7.1 and gcc 3.4).
When C++ 0x supports auto keyword (similar to gcc typeof), we'll probably be able to make the code a lot simpler and make the macros simpler.
|
|
|
|

|
Sorry for the sudden glut of questions - they correspond to a rush of enthusiasm, not criticism. In c++ the following is legal: class MyInterface { public: virtual void Write(void) = 0; virtual void Write(std::string Name) = 0; } Is the corresponding RCF declaration valid? i.e. are duplicate method names permitted where the method signature differs? e.g. RCF_BEGIN(IMyInterface, "IMyInterface") RCF_METHOD_V0(void, Write) RCF_METHOD_V1(void, Write, std::string) RCF_END
|
|
|
|

|
Just when I was about to start using RCF in anger, having played with it under a variety of compilers, I ran into the following: [C++ Error] _alloc.h(134): E2268 Call to undefined function '__stl_new' with Borland C++ Builder 6, using the RogueWave STL libraries (by #defining _USE_OLD_RW_STL) It fails to compile because there is no hash_map in RogueWave STL Unfortunately I can't swap to STLPort - BCB6 & STLPort in combination can produce some very odd errors from deep within std::string My workaround for now has been to change the Library section of Platform.hpp so it uses the MSVC60 version of Library.hpp, my reasoning being that if it works with the most broken of compilers then BCB6 should cope. <code>// Library #if defined(_MSC_VER) && _MSC_VER < 1310 #include "Library/msvc60/Library.hpp" #elif defined(_MSC_VER) #include "Library/msvc71/Library.hpp" #elif defined(__BORLANDC__) # ifdef _USE_OLD_RW_STL // # include "Library/msvc60/Library.hpp" // # else // new stuff # include "Library/bcc55/Library.hpp" // # endif // #elif defined(__GNUC__) #include "Library/gcc32/Library.hpp" #elif defined(__MWERKS__) #include "Library/cw80/Library.hpp" #else #include "Library.hpp" #endif</code> Is there a better fix?
|
|
|
|

|
Hi,
How can I shut down the service? Is there any standard way to do this?
Thanks,
Tamas
|
|
|
|

|
Do you have any hints how can I use this project within a hybrid (Managed and Non-managed projects) solution?
I'd like to call simple functions from simple ANSI C apps to a managed application.
|
|
|
|
|

|
Hi,
Marvellous work. It is simple and easy to use.
I would like a little more detailed documentation though.
Ok, about memory leaks...
I am using your RMI code in MFC on VC++ .NET 2003 and
I get memory leaks unless I do the following in my CWinApp::ExitInstance()
delete util::TraceManager::getSingletonPtr();
delete &util::UtilTraceChannelHolder::get();
delete &RCF::RcfTraceChannelHolder::get();
delete &SF::Registry::getMutex();
delete SF::Registry::getSingletonPtr();
I use your code in the following manner:
1. I bind/start your RCF::RcfServer inside a thread which is
- created/started in my CWinApp::InitInstance() and
- stopped/destroyed in the CWinApp::ExitInstance().
2. I get from your code that those classes are singletons made with new.
3. Not using boost serialization. Using your SF framework.
4. RCF_USE_BOOST_THREADS is not defined. Maybe it should ?
Is there some method to Init, deinit the util::trace tools ? and SF::Registry ?
If not there would certainly be a need for it.
Are your singletons self-deleting ?
I don't mind using my work around but I guess you'll want to have a look at this. I used Software Verification's Memory Validator to get details on what
was leaking since VC++ is scarce on details.
Thanks,
Alexandre Senechal, ing. jr
Programmer
Optifor inc.
|
|
|
|

|
Hi,
Your work looks very good and seems to be exactly what I need for my light program.
Unfortunately, I've got VisualC++ 6.0 and it doesn't appear that you test it with it.
Should it be easy to use RMI for c++ with VC6 ?
I tried to build your demo and Hello program, creating a new project, but I've got the following errors :
include\rcf\util\meta.hpp(98) : error C2989: 'Select' : template class has already been defined as a non-template class
include\rcf\util\meta.hpp(98) : error C2988: unrecognizable template declaration/definition
include\rcf\util\meta.hpp(101) : error C2989: 'Select' : template class has already been defined as a non-template class
include\rcf\util\meta.hpp(101) : error C2988: unrecognizable template declaration/definition
include\rcf\util\platform\library\msvc60\library.hpp(21) : fatal error C1506: unrecoverable block scoping error
Thanks for help
|
|
|
|

|
Beautiful. Put in the UDP support ASAP and you'll get a 6.
|
|
|
|

|
It certainly enhances usability to ditch Boost. In the next step also get rid of the ugly MFC-like macros (RCF_BEGIN, RCF_METHOD_R2, RCF_END, ...). It's 2005 not 1992
|
|
|
|

|
To be really cross platforms plus all the benefit of RMI/DCOM (whatever you name it...just a vendor game), SOAP is the way to go.
|
|
|
|

|
I've used a lot of remoting protocols and tools over the years from hand cranking my own, to ACE/TAO/CORBA, DCOM, XMLRPC, gSOAP,... and I like this a lot. Many times there is no need for anything especially scalable or with a huge amount of security baggage, just lightweight, quick and easy to use.
It's especially valuable to have the interface definition in code; it was that one feature which drew me to boost::spirit and subsequently the boost library in general. The only thing I don't like about it is the use of macros - e.g. RCF_METHOD_V1 - but that's personal prejudice.
I'd think I'd like to see more of boost::mpl to provide some of the functionality in meta.hpp, though that may be a short cut to obfuscation.
It also looks as though it should be possible to use boost::function and boost::bind to avoid the proliferation of RCF_METHOD_Rx macros, but I confess that I haven't looked hard at it yet.
I hope you'll consider submitting it to boost in due course.
Cheers!
|
|
|
|

|
What about DCOM? It’s one of ‘standard’ way to call remote components. In VS .NET you don’t even need idl, just use attributes. What is disadvantage of DCOM?
|
|
|
|

|
i just glanced over ur code and, while really impressive, it seems... unoptimized...
heres an example. Line 28 of include\idl.h:
return std::string(Name) == "" ? #InterfaceT : Name; \
could have been better written as
return !*Name ? #InterfaceT : Name; \
got my 5 tho =)
|
|
|
|

|
Hi Jarl,
Thanks for the very interesting article. A few questions and comments.
Have you looked at XML-RPC at all? If so how does it compare with your approach. I'm a big fan of XML and quite like the idea of XML-RPC, even though I've never used it.
You mention performance and replacing your own serialization framework with Boost.Serialization. I'm curious why you did this given the performance degradation. BTW I am also a big fan of Boost.
Finally on performance, I would have thought the real life bottleneck would be in the network connection and that the serialization etc. would have little overall impact. I appreciate running the client and server on the same PC is an exceptional case.
I've glanced sideways at ACE a few times over the years and after seeing the comments here I'm glad I've never tried to develop a serious relationship with it.
There was a post in The Lounge a day or so back about Spread http://www.spread.org/docs/spreadoverview.html[^] which I'd never heard of. This might be of interest to you.
Thanks again for the article. Got my 5.
Neville Franks, Author of ED for Windows www.getsoft.com and Surfulater www.surfulater.com "Save what you Surf"
|
|
|
|
|

|
The really interesting thing would be if a C++ client could talk to a Java server (or the other way around) using the standardized Java RMI protocol (at least a subset)!
Maybe such an implementation already exists somewhere?
|
|
|
|

|
Still have to look at the source, but damn, it's way way simpler than any other methods i've come across.
Good work
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
User-friendly remote method invocation in C++.
| Type | Article |
| Licence | CPOL |
| First Posted | 7 Feb 2005 |
| Views | 440,836 |
| Downloads | 3,428 |
| Bookmarked | 144 times |
|
|