5.4 Development of the server


  • 5.4.5 Simple verification of the server

    No mention to the implementation of the client, but visually experience the effect of the server development by using the HTML5 via chrome browser.

    • Experiment 5


      private MySessionView(SessionView.CreateParameter param) {
          super(param);
          // bind here
          long sessionid = param.getSessionId();
          bindMytable(sessionid);
          Procedure.execute(() -> {
              xbean.MyXbean xb = table.Mytable.insert(sessionid);
              if (xb != null) xb.setVar0(100);
              return true;
          });
          MyGlobalView gview = MyGlobalView.getInstance();
          gview.setVar0(new xbean.MyCbean(123));
      }
      

      Run the server, refresh the chrome web page, and the result is the same as the output of the experiment 3.

      Add a new line gview.syncToClient(sessionid) after the last line of the function.

      From the line 1, the var0 field of the MyGlobalView is set as 123 and sent to the client. The GlobalView need to be manually synchronized if used.

      Add two lines gview.syncToClient(sessionid) in the last of the functoin.

      In the line 2 and line 3, the status is REPLACE. But the data is no changed, why is it not TOUCH?

      The reason is simple: the GlobalView maintains the latest version of the data, and synchronizes the latest version data to the one or multiple clients through manually refreshing. The GlobalView would not record the sending history for the particular client. So the GlobalView never notifies the TOUCH status.

      Equally, if the field data is deleted, the status of the field data is not existed, so it is not be synchronized to the client when syncToClient. It means that the GlobalView never notifies the DELETE status.

      For the convience of the client implementation, avoid to use the DELETE semantics of the GlobalView field.


    • Experiment 6


      private MySessionView(SessionView.CreateParameter param) {
          super(param);
          // bind here
          long sessionid = param.getSessionId();
          bindMytable(sessionid);
          Procedure.execute(() -> {
              xbean.MyXbean xb = table.Mytable.insert(sessionid);
              if (xb != null) xb.setVar0(100);
              return true;
          });
          MyTemporaryView tview = MyTemporaryView.createInstance();
          tview.getMembership().add(sessionid);
      }
      

      MyTemporaryView.java


      @Override
      protected void onAttached(long sessionid) {
          MySessionView.getInstance(sessionid).setVar0("onAttached");
      }
      

      Run the server and refresh the chrome web page.

      Line 2: the TemporayView's onopen function is called.

      Line 3: the var0 of the SessionView is created as "onAttached".

      Check the below xml description.


      <subscribe name="_var0" ref="MySessionView.var0" />
      

      The temporary view subscribes the MySessionView.var0 and names it as _var0 here.

      Line 4: the _var0 of the TemporaryView is set as "onAttached".

      Unfolding the content of the View object, the _var0 is described in the 57344 element which is the current sessionid. The subscription effect of the TemporaryView is expressed in the client as the following: the subscribed information of each member is described in the member element with the sessionid as the key.

      Modify the example.html, add the below line after the v100.share.MyTemporaryView.onchange.


      ctx.send(v100.share.MyGlobalView, e.view.__i__);
      

      Implement the onMessage function in the MyGlobalView.java.

      MyGlobalView.java


      @Override
      protected void onMessage(String message, long sessionid) {
          MyTemporaryView.getInstance(sessionid, Integer.parseInt(message)).getMembership().remove(sessionid, (byte) 33);
      }
      

      Run the server and refresh the chrome web page.

      There is extra line 5. It should be explained like the below:

      After the line 4 is output, the instanceid of the TemporaryView as the message is sent to the GlobalView.

      The GlobalView implements the onMessage method, resolving the instanceid and obtaining the TemporaryView, removing the user from the Membership, which causes the client close this TemprorayView.

      It can be seen here that the Control and Message have the globl meaning, just like the description in this manual:

      "Although the Control is defined in the namespace of the View, it does not mean that the implementation of this Control can only change the current View."


    • Experiment 7

      This experiment detailedly explains the behavior of the TemporaryView, and the behavior is complicated.

      Remove all the previous modification.

      Copy example.html to example1.html, and change the username in the example1.html.

      example1.html


      private static Object lock = new Object();
      private static MyTemporaryView tview;
      private MySessionView(SessionView.CreateParameter param) {
          super(param);
          // bind here
          long sessionid = param.getSessionId();
          setVar0("hello " + sessionid);
          synchronized (lock) {
              if (tview == null)
                  tview = MyTemporaryView.createInstance();
              tview.getMembership().add(sessionid);
          }
      }
      

      MyTemporaryView.java


      @Override
      protected void onAttached(long sessionid) {
          MySessionView.getInstance(sessionid).setVar0("onAttached " + sessionid);
      }
      

      Run the server and refresh the chrome web page.

      Launch a new chrome, press F12 to active the debug, and drag the example1.html into the chrome.

      Figure 1, the debug window of the example.html

      Figure 2, the debug window of the example1.html

      In the figure 1, the first 5 lines could be explained by the previous example.

      In the figure 2,

      Line 1, the user represented by the figure 2 adds into the same TemporaryView of the user represented by the figure 1. So the two members [57344, 53248] could be seen behind the onopen.

      Line 2, "_var0 onAttached 57344", is the latest information of the subscribed var0 of the member 57344.

      Line 3, "_var0 hello 53428", is the latest informationn of the subscribed var0 of the current user.

      Line 4, the MySessionView.var0 of the current user is set as "hello 53428".

      So, a question is raised here that maybe the line 3 and line 4 are in the wrong order. Actually, it is the description in this manual:

      "The client could reproduce the fields' order in the same View which is modified by the server; the sequence between the different Views could not be ensured".

      In the figure 1,

      Line 6, "onattach 53428", means that the second member 53428 is added.

      Line 7, the information "hello 53428" of the subscribed var0 of the member 53428 has been sent here.

      In the figure 2,

      Line 5, the MySessionView.var0 is set as "onAttached 53428" when onAttached.

      Line 6, the subscribed information is sent to itself.

      In the figure 1,

      Line 8, the subscribed information "onAttached 53428" of the member 53428 is sent here.

      Comparing the expanded information between the line 7 in the figure 1 and the line 8 in the figure 2, they are exactly the same. Here you could see the contents of the TemporaryView of these two clients are fully synchronized.

      It is more complicated and briefly summarizes the behavior. When the user joins the Membership:

      1. Collect the new user's all subscribed information and broadcast to the other users as the attach message.

      2. The View information (variable, bind), with the other user's all subscribed information together are sent to the new user.

      3. The framework with the new user's sessionid as the paramter calls the onAttached method of the View instance of the server.

      We suggest the user try the experiment of leaving the view by himself because it is simpler.

      There are two cases for consideration.

      Membership.remove removes the user:

      1. Send the close message to the leaving user.

      2. Send the detach message (with the reason parameter of the Membership.remove together) to ther other users.

      3. The framework with the left user's sessionid and reason as the parameters calls the onDetached method of the View instance of the server.

      User disconnect:

      1. Send the detach message (with the -1 as the reason) to the other users.

      2. The framework with the disconnected user's sessionid and reason = -1 as the parameters calls the onDetached method of the View instance of the server.

      Finally, when the temporary View closes,

      1. Send the close message to all the users.

      2. The framework reverses all users' sessionid, and with reason = -1 together as the paramaters to call the onDetached method of the View instance of the server one by one.


    • Conclusion

      The several experiments above simply demonstrate the use of the View. The design of the protocol mode could be reflected to the View system through analogying the protocol mode: considered from the server, an unique SessionView is created, only uses the variable element, names the element with the protocol name, and the type is the Bean organized according to the protocol's field. Therefore, the View provides a far more powerful network application programming ability compared with the protocol mode, and completely does not care about any network programming detail.


Prev Next