How to distinguish clients on the server side

Intended audience: advanced developers, Programming language: c++

Problem overview

Some times Tango device is not just about talking with the hardware. Now-days a Tango device could be a sophisticated thing that performs complex work and serves numbers of clients simultaneously. And it might be required that the context of these clients may vary (context - a set of parameters of the task or result configuration etc). This is especially true due to multithreading reality we have.

Detailed cases

Client wants to specify in which format it receives an output from the server. Lets say it can be plain text or JSON or XML etc.

Server runs several tasks in parallel. One task per client. And each client wants to know its task ID, let’s say to control or monitor the task’s execution.

Solution overview

CORBA provides clnt_idnt, i.e. client identity. This can be used to create a concurrent map: ClientIdentity -> Context. And then each requests from the client can be served within the specified context.


 1    //
 2    //ConcurrentMap to hold each client's context
 3    private final ConcurrentMap<String, RequestContext> ctxs =  Maps.newConcurrentMap();
 5    //see Tango Java API for deviceManagment
 6    @DeviceManagement
 7    private DeviceManager deviceManager;
 9    //this will be an attribute, each client will see its own value
10    @Attribute
11    //this method returns client identity from CORBA as String
12    public String getClientId() throws Exception {
13        //deviceManager exports CORBA's client identity feature
14        return ClientIDUtil.toString(deviceManager.getClientIdentity());
15    }
17    //command that returns its result in the format defined in the client's context
18    @Command
19    public String doJob() throws Exception {
20        String clientId = getClientId();
21        RequestContext ctx = ctxs.get(clientId);
22        switch(ctx.outputType){
23            case OutputType.PLAIN:
24                return plainResult();
25            case OutputType.JSON:
26                return jsonResult();
27        }
28    }
 1    //
 2    //NOTE this class must be thread safe
 3    @Immutale
 4    public class RequestContext {
 5        //OutputType is an enum
 6        public final OutputType outputType;
 8        public RequestContext(OutputType outputType) {
 9            this.outputType = outputType;
10        }
12        /**
13         * Creates default context
14         */
15        public RequestContext() {
16            this(OutputType.PLAIN);
17        }
18    }