Skip to main content
February 16, 2010
Answered

Lock in FMS code

  • February 16, 2010
  • 1 reply
  • 1697 views

Hi,

       Does anybody has idea about locking system in FMS server side code. Like we have locking system in Coldfusion and other technologies (CF lock).

Like shared objects we have lock, but what If I want to implement lock on the particular script. For example at onConnect of any user to FMS,  I have script which is doing 8-9 different tasks before or after accept the user for that FMS application session (including remoting calls).

Now if 20 users came at the same time in the same room, how will FMS execute them and process the 8-9 task, which user will be executed first and who would be next.

In short, how FMS will execute the piece of code or process for multiple user at the same time.

So locking system can fix this problem I think.

Is  there anything else we can do to make this system better.

Looking forward any help in this area. If there is any expert please suggest the best solution.

Thanks,

Amitabh Arya

    This topic has been closed for replies.
    Correct answer Janaki Lakshmikanthan

    Hi,
    >> Right, having limited logic at the client side will be the good choice.

    >> The intention why i proposed the second solution is if you have any variables

    that are declared globally (i meant the usual 'global' property of OOPS concept)

    which are exposed in the functions and are used by multiple clients at the same

    time. Any kind a variables that you are using at the server side code which are

    shared across the clients during simultaneous calls. Taking you example, you have

    to make a remote call to a database or something else. Is your remote call or

    database is capable of managing simultaneous calls? If so, then for your case the

    1st solution suits. Like you have mentioned, keeping the huge number of clients

    on hold will not suit your case.
    FMS maintains a unique ID for every client connected to the server which is

    called 'clientID'. This value might not be unique across the clients connected to

    different fmsCore processes, but it is definitely unique for clients within a

    core process. SO using this ID you are sure you can find the right client.

    Now back to the first solution... let us take simple example of 3 clients

    connecting to the server simultaneously... how do they process the server side

    code.

    application.onConnect = function(clientObject){
             
      clientObject.method_1(){
            //clientObject.method_2();
      }
     
      clientObject.method_2(){
            //clientObject.method_2();
            //so on
      }

    clientObject.method_1();
      
       application.acceptConnection(clientObject);
       //or application.rejectConnection(clientObject);
      }
    }

    All the 3 clients are connecting to the server at the same time. They all call

    onConnect method with reference to their client objects. So the method_1,

    method_2 which are defined at the server side is instantiated for all the 3

    clients. SO they have their own methods to works with. So inside these methods,

    if we have statements that make remote calls, all the 3 clients will make the

    remote calls simultaneously. SO your database should be able to handle multiple

    clients simultaneously. If so, then this approach will suit your case. So any

    operation that we perform will be on client Object, hence that makes the

    difference in interacting the FMS server with its right client.

    Where did you get secure.asc file from? I am not sure about such a file in fms. Was it installed along with FMS or it is your custome asc file for your application?

    Regards,
    Janaki L

    1 reply

    Janaki Lakshmikanthan
    Adobe Employee
    Adobe Employee
    February 18, 2010

    Hi,
    This is an interesting question. You can achieve this by the 2 ways mentioned

    below

    Method:

    You declared all the tasks that you want to perform for a client inside a

    method on client object. And place this method inside application.onConnect() method.

    application.onConnect = function(clientObject){
             
      clientObject.method_1(){
            //clientObject.method_2();
      }
     
      clientObject.method_2(){
            //clientObject.method_2();
            //so on
      }
    clientObject.method_1();
      
       application.acceptConnection(clientObject);
       //or application.rejectConnection(clientObject);
      }
    }

    But using this approach you cannot use global variables within these clientObject

    methods, as they will be shared across the clients.

    Method 2:

    If you still want to use global varialbles, then you can try this one.
    Whenever a client tries to connect, store the client ID in an global array say

    clientIdArray[]. Then accept the connection from the incoming clients. Here dont

    perform your other tasks inside application.onConnect() method. Keep the tasks

    under another application method say application.startMyTask = function() {}. For

    the first client you call your custom application method startMyTask directly at

    the server side. For the later clients do not call this method until the first

    client finishes the operation. Once the first client finishes the operation, you

    use application.broadcastMsg() method like
    application.broadcastMsg("methodOnClient");
    which will call all the active clients on that application instance. Define a

    handler to receive this call at the client side, which inturn will call the

    server again.


    nc.methodOnClient = function(){
    nc.call("checkClientID", null, null);
    }

    FOr which you should have the handler at the server side like...

    clientObject.checkClientID = function(){
    if(this client id is the next client id)
      application.startMyTask();

    }

    application.startMyTask = function() {
    //Do your tasks
    //Increment your counter
    application.broadcastMsg("methodOnClient");
    }

    Once the second client finishes the task, broadcast message to all the clients

    and continue the same until you finish the tasks for all the clients.

    So your code would be like this..

    ** client side code **

    var nc = new NetConnection();
    nc.connect("rtmp://your_server/your_application" );
    nc.onStatus  = function(info){
    if(info.code == "NetConnection.Connect.Success"){
            //wait for broadcast
    }
    }
    nc.methodOnClient = function(){
               nc.call("checkClientID", null, null);

    }

    ** server side code **

    var clientIdArray = new Array();
    var incomingCounter = 0;
    var completedCounter = 0;
    application.onConnect = function(clientObject){
          clientIdArray[incomingCounter++] = clientObject.id;
        
          clientObject.checkClientID = function(){
                    if(this client id is the next client id)
                                 application.startMyTask();
          }
          application.acceptConnection(clientObject);
               //Call startMyTask method for first client
               if(incomingCounter == 1)
                     application.startMyTask();

    }

    application.startMyTask = function(){

          //Do your task

          //When done increment the completedCounter
          application.broadcastMsg("methodOnClient");
    }

    You can have a flag at the client side to avoid calling the server side method "checkClientID" if it has done the tasks already. So that the server method is not simply called by the completed clients.

    If you have found better approach, do share with us

    Regards,
    Janaki L

    February 22, 2010

    Hi,

                Thanks for replying. Both methods are really good. First I thought to reply you as this is the best answers but then I decided to discuss it little more in depth and to reach the best solution. As you are sounding a good FMS professional to me  .

    Before discussing further let me introduce with some of my concerns:

    >> I am rewriting this application for one of my client. (Some other guy wrote this earlier for them)

    >> In current scenarios, the application each instance (each room) has about 50 users at the time.

    >> On every connect and disconnect, there is a  remoting call to update the database, writing the logs in a text file (from FMS only) and much more logic and checks.

    >> There are multiple servers and every server has the same version of application code.

    In 2nd solution, (this should be the perfect solution, what Adobe should code in FMS by default ) But I have few points to discuss

    >>  The main part of connection (connection business logic) is depend on client side code, while I think to keep the complete code (business logic) at server side is more secure.

    >> Its a long process, while you are using it with remoting. As user will come, put him in array, wait for completion of last process, and broadcast client method. Clients will call the server methods back, start the process for next user, process the checks, initiate remoting and call the remoting methods, wait for remoting callback (result) and then accept the user finally. Its still fine for application where we have 5-6 users but I think we should not count on this solution if we are talking 50 connection at the same time. If at any point FMS skips the code or doesn't process it then it will be a break and will take time to debug it.

    >> The main problem is still not fixed (How FMS manage the multiple users at the same time). As multiple users will come at the same time, how can we assure that FMS will assign different index to each user or push each user in array with different index. Because the problem is not to process the one line code or multiple code lines but to manage the multiple users at the same time, who will be first and who will be next, How FMS will decide this.

    In 1st solution, sounds good to me. But

    >> As FMS creates different instance for each users and provide a different client id, so create a client level function at server and process the whole business logic of accepting a client in that, make more sense to me.

    But I am confused that what you mean by "cannot use global variables", what kind of global variables are you talking here, is that trace or setIntervals or something else. And is there any security issue to use the client object functions to accept the clients. Please verify .

    One more things, (I might be going away from topic). Do you have any idea about secure.asc file what it does.

    Once again Thanks for your replying. Looking forward to your replies again 

    Amitabh Arya

    Janaki Lakshmikanthan
    Adobe Employee
    Janaki LakshmikanthanCorrect answer
    Adobe Employee
    February 23, 2010

    Hi,
    >> Right, having limited logic at the client side will be the good choice.

    >> The intention why i proposed the second solution is if you have any variables

    that are declared globally (i meant the usual 'global' property of OOPS concept)

    which are exposed in the functions and are used by multiple clients at the same

    time. Any kind a variables that you are using at the server side code which are

    shared across the clients during simultaneous calls. Taking you example, you have

    to make a remote call to a database or something else. Is your remote call or

    database is capable of managing simultaneous calls? If so, then for your case the

    1st solution suits. Like you have mentioned, keeping the huge number of clients

    on hold will not suit your case.
    FMS maintains a unique ID for every client connected to the server which is

    called 'clientID'. This value might not be unique across the clients connected to

    different fmsCore processes, but it is definitely unique for clients within a

    core process. SO using this ID you are sure you can find the right client.

    Now back to the first solution... let us take simple example of 3 clients

    connecting to the server simultaneously... how do they process the server side

    code.

    application.onConnect = function(clientObject){
             
      clientObject.method_1(){
            //clientObject.method_2();
      }
     
      clientObject.method_2(){
            //clientObject.method_2();
            //so on
      }

    clientObject.method_1();
      
       application.acceptConnection(clientObject);
       //or application.rejectConnection(clientObject);
      }
    }

    All the 3 clients are connecting to the server at the same time. They all call

    onConnect method with reference to their client objects. So the method_1,

    method_2 which are defined at the server side is instantiated for all the 3

    clients. SO they have their own methods to works with. So inside these methods,

    if we have statements that make remote calls, all the 3 clients will make the

    remote calls simultaneously. SO your database should be able to handle multiple

    clients simultaneously. If so, then this approach will suit your case. So any

    operation that we perform will be on client Object, hence that makes the

    difference in interacting the FMS server with its right client.

    Where did you get secure.asc file from? I am not sure about such a file in fms. Was it installed along with FMS or it is your custome asc file for your application?

    Regards,
    Janaki L