Archived

This forum has been archived. Please start a new discussion on GitHub.

Need help with several adapters in one application

Hello,

I am newby with Ice - this is my first try with it, so my question may be stupid.

I need help with having several adapters working inside one application.
I am using Visual Studio 2008, C# 3.5 and Ice 3.3.0.
I am building a system which consists of two main elements: server and client. Client is responsible of sending some commands to the server (something like start an external app, stop an external app, etc). The server is resonsible of retrieving commands from the client, process them and send the server state to the client. I am using Ice\bidir project as an example.

Everything is working fine until I have only one instance of the adapter inside my client app. But when I add one more adapter (which is working with another server) I have problems. Both adapters are connecting to one server instead of connecting to corresponsing server. Servers are running on different machines, each adapter has it's own config file. Each adapter is running in it's own thread started by the application.

Can someone help me with this?
Thanks

Comments

  • matthew
    matthew NL, Canada
    renkin wrote: »
    ... send the server state to the client. I am using Ice\bidir project as an example.

    Do you need to use bidirectional communications for a specific reason?
    ..., each adapter has it's own config file. Each adapter is running in it's own thread started by the application.

    You haven't actually said what is going wrong. Without getting specific it is very hard to help :)

    I don't understand what you mean by these last two points. Why do you run the adapter in a separate thread? How do you give each adapter its own configuration file? Furthermore, why are you creating two adapters? It is NOT necessary to create more than one adapter in the client to connect with more than one server.

    For some general hints, I would start by simplifying your application. It is almost never necessary to have multiple adapters (see http://www.zeroc.com/faq/multipleOA.html). If you don't need bidirectional communications, I would get rid of that too. You should turn on more network level tracing to find out what is going on in your application (Ice.Trace.Network=3 will give you LOTS of information).

    If after doing this you still cannot figure out what is going wrong, then the best way to get help is to post a self-contained, complete & compilable example that demonstrates your issue.
  • Let me explain the system in more details:
    we have two servers located on different computers in a network. Both these servers have the same logic - they are running some external application, checking their states and retrieving some data from these application. Also, we have one client, which has to be connected to both these servers, has an ability to manage these servers' activity (sends command to start the external application, stop them). Also, this client is responsible for retrieving collected by servers data, process it and save it into a data base. This is why we need bidirectional communications. May be we can have one adapter connected to two servers and working with them - i do not know.

    I have two separate threads because of if i run communicator().waitForShutdown() method it will "hang" the current thread.

    Also, i attached my simple application which is based on the example application located in democs\Ice\bidir folder. All I changed is the client application to create two data adapters. You need to run servers applications on different computers in a network and change clients' config files to use valid IP addresses of servers.

    Also, I tried to set Ice.Trace.Network=3 in all config files (for servers and clients) and I saw that both clients were connected to one server and after it one client was removed from the server.
  • dwayne
    dwayne St. John's, Newfoundland
    renkin wrote: »
    ... Also, this client is responsible for retrieving collected by servers data, process it and save it into a data base. This is why we need bidirectional communications.

    Just because your client also needs to receive requests from your servers does not mean that you have to use bidirectional communication. You only need to use bidir in cases where otherwise your server would not be able to establish a connection to the client because, for example, it is behind a firewall. If such is not the case, then your client can just act as a regular Ice server the same as your server application.

    Note that terms client and server can get confusing here when a single application acts as both a Ice server and Ice client.
    May be we can have one adapter connected to two servers and working with them - i do not know.

    As Matthew stated, the case is rare that multiple adapters are required and I am pretty certain that your use case is not one of them.
    I have two separate threads because of if i run communicator().waitForShutdown() method it will "hang" the current thread.

    It is not necessary for you to call waitForShutdown() if you do not need to. If you want to continue using the current thread for your app you can do so instead of calling it.
    Also, i attached my simple application which is based on the example application located in democs\Ice\bidir folder. All I changed is the client application to create two data adapters. You need to run servers applications on different computers in a network and change clients' config files to use valid IP addresses of servers.

    Also, I tried to set Ice.Trace.Network=3 in all config files (for servers and clients) and I saw that both clients were connected to one server and after it one client was removed from the server.

    You are not only creating multiple adapters, you are also creating multiple communicators since you are creating two instances of the Ice::Application class. First of all creating multiple communicators is necessary in even fewer instances than it is necessary to have multiple adapters. Secondly Ice.Application is really not meant to be used multiple times in a single process.

    Having said all of that, I did try running your modified bidir demo as is and the client connected to both servers. I did not use multiple machines but instead ran two servers on the one machine listening on different ports, but the difference should be the same. I did notice that in one of your client config files you are not specifying a host in the proxy configuration. Maybe that is the cause of the behavior you are seeing?
  • Hello Dwain,

    thank you for your response, but it really strange that my code is working for you - it's not working for me even when i run two servers on the same machine and specifying ip address for servers.

    I read you comment, it seems that I did my test application (and main system too) in a wrong way.

    But it's still not clear for me how I should implement this.

    Could you please fix my test application attached to this topic to work in the proper way?

    Thanks
  • dwayne
    dwayne St. John's, Newfoundland
    Attached is modified source and config to run the bidir demo with two servers on the same machine. To run it you need to do the following:

    > server.exe --Ice.Config=config.server1
    > server.exe --Ice.Config=config.server2
    > client.exe

    It should run equally well using multiple machines by changing the Proxy/Endpoint configurations in the config files appropriately.

    If it is still not working for you please post the network tracing that you get from running the executables.

    Finally, as we stated before, it is most likely that you do not actually need to be using bidir and could just use regular connections. With bidir connections the connection must always be active in order for the "server" to be able to communicate with the "client". If the connection is dropped for any reason then the server would not be able initiate any new communication , but must wait for the client to reestablish the connection. Therefore unless it is necessary to use bidir for reasons such as firewalls, I would recommend that you not use it.
  • Hello Dwayne,

    thank you for the example - now it's clear for me.

    but i still have one question: in one of your replies you said that i do not need to use waitForShutdown() method in my code. I changed my application to not use this method and it seems that after initial connect to the server and recieved some information, the server retrieves "waitForShutdown()" message from the client. How can i prevent this? The adapter is working inside a GUI application, so the main thread is still working and i am sure i did not send this command to the server directly in my code. If I use waitForShutdown() method, everything is working fine. I just want to know how I can do not use waitForShutdown() method?

    Thanks
  • matthew
    matthew NL, Canada
    What do you mean the server retrieves waitForShutdown from the client? That is impossible, waitForShutdown() waits for shutdown to be called on the communicator, it does not send any message (other than the connection close protocol message, which is invisible to the application). You must be calling some method on a proxy which causes the server to call shutdown on the communicator. Turn on protocol tracing, and you'll be able to see what messages flow over the wire.

    Ice.Trace.Protocol=1
  • Sorry,

    I meant "received close connection" command. All I changed is running the adapter inside the main GUI thread and commented waitForShutdown() method inside the adapter.
  • dwayne
    dwayne St. John's, Newfoundland
    The mostly likely reason for this is that you are allowing the Ice.Application run() method to return prematurely, which causes the communicator to be destroyed. When I said that it is not necessary to call waitForShutdown() I meant that instead you can just run your application loop there instead. However, you cannot just remove the waitForShutdown() and let the run() method return.
  • Thank you for helping me - everything is working as i need now.