Archived
Multiple Clients for one Server (Java)
Comments
-
Yes, this is possible. Just be aware that the default size for the server-side thread pool is 1, meaning only one request will be dispatched at a time. If you need multiple requests to be dispatched simultaneously, you'll have to increase the maximum size of the server-side thread pool.
0 -
" meaning only one request will be dispatched at a time " => Only one client can call server methods at the same time ?
0 -
In fact, I need that during a server method calling, an other client call an other server method to set a class attribute (server class) in order to provide the information needed by the return value of the method called by the first client
0 -
Only one client can call server methods at the same time ?
Yes, in the default configuration.
In fact, I need that during a server method calling, an other client call an other server method to set a class attribute (server class) in order to provide the information needed by the return value of the method called by the first client
In this case you will need to configure the server-side thread pool in the server to have at least two threads:
Ice.ThreadPool.Server.Size=2
0 -
Could you tell me where I must set the attribute value ?
0 -
There are several ways to set configuration properties:
- in a configuration file
- on the command line
- in your code
0 -
Thanks.
Consequently, by code I must add
local interface Properties
{
void setProperty("Ice.ThreadPool.Server.Size", "2");}
in Slice definition ?
0 -
Not in your Slice definition, this goes in your server code. For example:
public static void main(String[] args) { com.zeroc.Ice.InitializationData initData = new com.zeroc.Ice.InitializationData(); initData.properties = Ice.Util.createProperties(args); initData.properties.setProperty("Ice.ThreadPool.Server.Size", "2"); com.zeroc.Ice.Communicator communicator = Ice.Util.initialize(initData); ... }
0 -
com.zeroc.Ice.InitializationData initData = new com.zeroc.Ice.InitializationData(); initData.properties = com.zeroc.Ice.Util.createProperties(args); initData.properties.setProperty("Ice.ThreadPool.Server.Size", "2"); try(com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(initData)) { com.zeroc.Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithEndpoints("clientmetaserveurAdapter", "default -p 10000"); com.zeroc.Ice.Object object = new ClientMetaServeurI(); adapter.add(object, com.zeroc.Ice.Util.stringToIdentity("clientmetaserveur")); adapter.activate(); communicator.waitForShutdown(); }
is correct ?
0 -
Yes that looks correct.
0 -
In the Java Mapping for struct example :
public final class Employee implements java.lang.Cloneable, java.io.Serializable
{
public long number;
public String firstName;
public String lastName;public Employee() {} public Employee(long number, String firstName, String lastName) { this.number = number; this.firstName = firstName; this.lastName = lastName; } public boolean equals(java.lang.Object rhs) { // ... } public int hashCode() { // ... } public java.lang.Object clone() { java.lang.Object o; try { o = super.clone(); } catch(java.lang.CloneNotSupportedException ex) { assert false; // impossible } return o; }
}
public boolean equals(java.lang.Object rhs) and public int hashCode() must be empty ?
0 -
Not sure I understand your question. slice2java does generate code for those methods, we just don't show it in the manual. You can run slice2java and then review the generated code if you want.
0 -
In fact, I don't need to write myself the java mapping code for struct, it will be automatically generated by slice2java (like String or void types in Slice definition automatically generated...) ?
0 -
That's correct.
0 -
Thanks, could you tell me if com.zeroc.Ice.Current current in parameter of a server method not called by the client (used by server himself) is required ?
0 -
The Ice run time automatically supplies the
Current
argument to every servant method. Your servant methods must declare this parameter even if you don't use it.0 -
An Ice client must be instantiate in a main function, or it can be everywhere... ?
In fact, One of my ice clients is also an IceStorm Subscriber.
On Topic message receiving, the client must call an ice server method.
To do this, I would like to instantiate, use and close an ice client "dynamically" (on some message received contents...)
0 -
A
Communicator
represents an instance of the Ice run time. I'm guessing that this is what you mean when you say "ice client". You can create a communicator anywhere, but you also have to ensure the communicator is destroyed. Note that it's not usually necessary for a program to create more than one communicator, and in fact it would be somewhat inefficient to repeatedly create and destroy a communicator every time you needed to make an invocation.Take a look at our IceStorm subscriber example. It shows how to implement a subscriber and properly handle the destruction of the communicator.
0 -
In fact, I'm trying to instantiate an IceClient in a Java Class Constructor, its possible... ?
0 -
We would need to see some code in order to answer that.
0 -
Sorry for the delay, I'm very busy with many tasks to do...
I need that an IceStorm Subscriber send an answer to an Ice Server by creating a temporary Ice Client to call Ice Server methods....
In order to do that, I think put IceClient in a Java Class and simply crean an object when I need to create a Ice Client to send an answer to Ice Server
A part of my IceStorm Subscriber code (ClientServeur is the class in which IceClient is coded)
if (m.message.length() > 0) { String[] trame=m.message.split(","); if(trame[0].equals("Add")) { if(trame[2].equals("Serveur1")) { this.addMorceau(trame[1], curr); } } else if(trame[0].equals("Search")) { new ClientServeur(getMorceauByTitre(trame[1], curr)); } else if(trame[0].equals("Delete")) { this.deleteMorceau(trame[1], curr); } else if(trame[0].equals("List")) { new ClientServeur(new String("Serveur1," + this.getListeMorceauxSerialise(curr))); } else if(trame[0].equals("Size")) { new ClientServeur(new String("Serveur1," + String.valueOf(this.listeMorceaux.size()))); } }
ClientServeur class :
public class ClientServeur {
public ClientServeur(String message) { try(com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize("")) { com.zeroc.Ice.ObjectPrx base = communicator.stringToProxy("clientmetaserveur:default -p 10000"); MP3.PrinterPrx printer = MP3.PrinterPrx.checkedCast(base); if(printer == null) { throw new Error("Invalid proxy"); } printer.setReponse(message); } }
}
0 -
Yes, you can do that. As I wrote earlier, it's not a very efficient strategy because initializing and destroying communicators is relatively expensive. But if this is something you only do occasionally, and it makes the code simpler, then go ahead. In general though, an application typically initializes a communicator once and uses it throughout the program.
0 -
Thanks, Could you tell me if its possible to share the same servant instance for 3 Ice clients ?
I have a list in servant class attribute and I need to share the list content with the ice clients (clients will remove, add on the same list...)
0 -
Yes, that is possible and very common. You should familiarize yourself with the Ice threading model, if you haven't already. By default, there is only one thread in the server-side thread pool, which means only one client request will be processed at a time. You can configure the thread pool with more threads, but then you'll need to use synchronization in the servant.
0 -
I think that I have a problem.
In the Ice servant object shared by all Ice clients, a method is blocking until all others client have no answered by calling a method on this servant object...
while(this.countSubstring("KGmqUPGJpe3DoRteSNPV", this.reponse, current) != this.listeServeurs.size());
The code is waiting until all client have answered
Ice can do that... ?
0 -
If I understand what you're asking, you want a Slice operation to block until the server has received requests from all clients? This is certainly possible, but again it raises threading issues. You'll either need to increase the size of the server-side thread pool so that there are at least as many threads as there are clients, or your servant can use AMD for its implementation.
0 -
I have an error when I run IceStorm Server :
threadClientMetaServeur (9) : START
Exception in thread "threadClientMetaServeur" com.zeroc.Ice.ConnectFailedException
error = 0
at com.zeroc.IceInternal.OutgoingAsync.waitForResponseOrUserEx(OutgoingAsync.java:146)
at com.zeroc.IceInternal.OutgoingAsync.waitForResponse(OutgoingAsync.java:118)
at com.zeroc.Ice._ObjectPrxI.ice_isA(_ObjectPrxI.java:36)
at com.zeroc.Ice.ObjectPrx._checkedCast(ObjectPrx.java:862)
at com.zeroc.Ice.ObjectPrx._checkedCast(ObjectPrx.java:824)
at com.zeroc.IceStorm.TopicManagerPrx.checkedCast(TopicManagerPrx.java:291)
at Serveur.MetaServeur$1.run(MetaServeur.java:23)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.ConnectException: Connexion refusée
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
at com.zeroc.IceInternal.Network.doFinishConnect(Network.java:541)
at com.zeroc.IceInternal.StreamSocket.connect(StreamSocket.java:96)
at com.zeroc.IceInternal.TcpTransceiver.initialize(TcpTransceiver.java:30)
at com.zeroc.Ice.ConnectionI.initialize(ConnectionI.java:2095)
at com.zeroc.Ice.ConnectionI.message(ConnectionI.java:1078)
at com.zeroc.IceInternal.ThreadPool.run(ThreadPool.java:416)
at com.zeroc.IceInternal.ThreadPool.access$500(ThreadPool.java:12)
at com.zeroc.IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:785)
... 1 moreCode :
public static void main(String[] args) throws Exception
{Runnable clientMetaServeurRunnable = new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getId() + ") : START"); com.zeroc.Ice.Communicator communicator = com.zeroc.Ice.Util.initialize(args); com.zeroc.Ice.ObjectPrx obj = communicator.stringToProxy("IceStorm/TopicManager:tcp -p 9999"); com.zeroc.IceStorm.TopicManagerPrx topicManager = com.zeroc.IceStorm.TopicManagerPrx.checkedCast(obj); com.zeroc.IceStorm.TopicPrx topic = null; while(topic == null) { try { topic = topicManager.retrieve("MP3"); } catch(com.zeroc.IceStorm.NoSuchTopic ex) { try { topic = topicManager.create("MP3"); } catch(com.zeroc.IceStorm.TopicExists ex2) { // Another client created the topic. } } } com.zeroc.Ice.ObjectPrx pub = topic.getPublisher().ice_oneway(); MP3.CommunicateurPrx monitor = MP3.CommunicateurPrx.uncheckedCast(pub);
Could you help please ?
0 -
A "connection refused" error usually means the target server (in this case, IceStorm) is not listening on the host and/or port that was specified in the proxy. Common reasons could be IceStorm isn't running, or IceStorm is listening on a different host/port combination, or the client's proxy is incorrect.
0 -
I must run another thing that IceStorm Publischer during the same time... ?
0 -
The IceStorm server is required. It relays messages between publishers and subscribers.
0