EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Get set a transport active

Also by EldoS: Callback File System
Create virtual file systems and disks, expose and manage remote data as if they were files on the local disk.
#19980
Posted: 04/30/2012 10:36:21
by Nicolas Ciezki (Standard support level)
Joined: 04/26/2012
Posts: 13

For now I made two little Android applications

The first one is the Client part :

Code
import org.eldos.MsgConnect.MCBase.*;
import org.eldos.MsgConnect.MCSocket.*;

public class msgconnectActivity extends Activity {
   
   private MCSocketTransport transport = new MCSocketTransport();
   private MCMessenger messenger = new MCMessenger();
   private MCMessage message;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        MCMessenger.setLicenseKey("...");
                                                          
        transport.setMessenger(messenger);
      transport.setTransportMode(MCInetTransport.stmClient);
      transport.setActive(false);
      
      ((EditText)findViewById(R.id.port)).setText("14584");
      ((EditText)findViewById(R.id.address)).setText("10.10.1.196");
        ((TextView)findViewById(R.id.TextActive)).setText("Inactif");
    }
    
    public void onButtonSendClick(View v) {
       
       String S = new S tring("HelloDroid");
        message = MCMessenger.createMessageFromText(1, 0, 0, S, null, false);
      
        String address = ((EditText)findViewById(R.id.address)).getText().toS tring();
        String port = ((EditText)findViewById(R.id.port)).getText().toS tring();
            
        try {
         messenger.postMessage("Socket:"+address+":"+port+"|SendNote", message, null);
      } catch (EMCError e) {
         e.printStackTrace();
      }
      
      Toast toast = Toast.makeText(getApplicationContext(), "Message envoyé", Toast.LENGTH_LONG);   
      toast.show();
   }
    
    public void onActiveButtonClick(View v) {
              
       transport.setActive(!transport.getActive());       
       
       if(transport.getActive()) {
           ((TextView)findViewById(R.id.TextActive)).setText("Actif");         
       }
       else {
           ((TextView)findViewById(R.id.TextActive)).setText("Inactif");
       }
    }
}


It's only send a "HelloDroid" message.

The problem is in my server part :

Code
public class MsgConnectServeurActivity extends Activity {
    
   private MCSocketTransport transport = new MCSocketTransport();
   private MCMessenger messenger = new MCMessenger();
   private MCQueue queue = new MCQueue();
   private java.util.Timer dispatchTimer = new java.util.Timer();
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        MCMessenger.setLicenseKey("...");
        
        transport.setMessenger(messenger);
      //transport.setTransportMode(MCInetTransport.stmServer);
      //transport.setMessengerPort(14584);
      transport.setActive(false);
      
        queue.setMessenger(messenger);
      queue.setQueueName("SendDroid");
        
      queue.addUnhandledMessageListener(new MCHandleMessageListener() {
         public boolean handleMessage(MCHandleMessageEvent e) {
            return queue_HandleMessage(e);
         }
      });
                        
      ((EditText)findViewById(R.id.EdtListeningPort)).setText("14584");      
      
      ((TextView)findViewById(R.id.TextActive)).setText("Inactif");
      ((EditText)findViewById(R.id.EdtListeningPort)).setEnabled(true);      
      
      //call dispatchMessage(), le timer sert à faire en sorte qu'on apelle cette méthode toutes les 100ms (à peu près...)
      dispatchTimer.schedule(new DispatchTask(), 1000, 1000);
    }
    
    public void onButActiveClick(View v) {       
       
       int port = Integer.parseInt(((EditText)findViewById(R.id.EdtListeningPort)).getText().toS tring());
       
       if (!transport.getActive()) {         

         transport.setMessengerPort(port);
         transport.setTransportMode(MCInetTransport.stmServer);

         try{
            transport.setActive(true);
         }
         catch(Exception ex){
            Toast toast = Toast.makeText(getApplicationContext(), ex.toS tring(), Toast.LENGTH_LONG);   
              toast.show();
         }
         
      }
       else {
         try{
            transport.setActive(false);
         }
         catch(Exception ex){
            Toast toast = Toast.makeText(getApplicationContext(), ex.toS tring(), Toast.LENGTH_LONG);   
              toast.show();
         }
       }
                
      if (transport.getActive()) {      
         ((EditText) findViewById(R.id.EdtListeningPort)).setEnabled(false);
         ((TextView)findViewById(R.id.TextActive)).setText("Actif");
      }
      else {
         ((EditText) findViewById(R.id.EdtListeningPort)).setEnabled(true);
         ((TextView)findViewById(R.id.TextActive)).setText("Inactif");
      }
    }
    
    //Calling when the incoming message occurred
     boolean queue_HandleMessage(MCHandleMessageEvent e) {
         
        boolean res = false;
        try {
           MCMessage message = e.getMessage();
           byte[] data = message.getData();
           
           if ((data != null) && (data.length > 0)) {

              Toast toast = Toast.makeText(getApplicationContext(), data.toS tring(), Toast.LENGTH_LONG);   
              toast.show();
              
              return true;
           }
           
        } catch (Exception ex) {
           String msg = ex.getMessage();
           if (msg != null)
              System.out.println(msg);
        }
        return res;
     }
     
     class DispatchTask extends java.util.TimerTask {        
        
      public void run() {            
         if (transport.getActive()) {
            try {          
                messenger.dispatchMessages();
            } catch (Exception e) {
               e.printStackTrace();
            }
         }      
      }
   }
}


For a weird reason, the transport cannot be set active...
#19981
Posted: 04/30/2012 10:53:49
by Eugene Mayevski (EldoS Corp.)

Please add permissions set for activity in the sample to your project. One of those is required for the server to run, but I don't remember which one :)

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />


Sincerely yours
Eugene Mayevski
#20005
Posted: 05/02/2012 03:00:14
by Nicolas Ciezki (Standard support level)
Joined: 04/26/2012
Posts: 13

Yes, it's the INTERNET permission. Thank you for that, I shall have taken time before thinking of it. Although I did it automatically with the client... -_-'

(ACCESS_NETWORK_STATE necessary if you want to get an access on the system service, useful to verify if your are connected on the internet, for example.)

By the way, queue_HandleMessage is never called after my client part sent the message.

Did I miss something ? :o
#20006
Posted: 05/02/2012 03:18:27
by Eugene Mayevski (EldoS Corp.)

Quote
rappunzell wrote:
By the way, queue_HandleMessage is never called after my client part sent the message.


And does the sample work?


Sincerely yours
Eugene Mayevski
#20007
Posted: 05/02/2012 03:20:04
by Eugene Mayevski (EldoS Corp.)

BTW the client in the code you posted above sends a message to "SendNote" queue while the queue name on the server is "SendDroid".


Sincerely yours
Eugene Mayevski
#20008
Posted: 05/02/2012 03:25:24
by Nicolas Ciezki (Standard support level)
Joined: 04/26/2012
Posts: 13

You mean SendNote ?

Yes, it works great. And SendNote receive 'HelloDroid' form my client part (just need to change the name of the queue in the postMessage), but only with the Android sample, not the Pascal's SendNote.

Sorry, I made a mistake on the code when I posted it, but the client sends indeed a message on the "SendDroid" queue.

Correct me if I make a mistake, but it's the dispatchMessages() method wich normally call the queue_HandleMessage(MCHandleMessageEvent e), does it ?


I tried to use the sample to send a message to my server part. It gives me the 5 error code, BadDestinationName. I don't know why, I correctly write the right IP address...
#20009
Posted: 05/02/2012 03:50:08
by Eugene Mayevski (EldoS Corp.)

Quote
rappunzell wrote:
Correct me if I make a mistake, but it's the dispatchMessages() method wich normally call the queue_HandleMessage(MCHandleMessageEvent e), does it ?


Yes, it's DispatchMessages.

Quote
rappunzell wrote:
I tried to use the sample to send a message to my server part. It gives me the 5 error code, BadDestinationName. I don't know why, I correctly write the right IP address...


This error is reported by the recipient when the queue is not found. Re-check that you use correct queue names on all sides.


Sincerely yours
Eugene Mayevski
#20024
Posted: 05/03/2012 02:49:03
by Nicolas Ciezki (Standard support level)
Joined: 04/26/2012
Posts: 13

Thanks a lot again.

1. A part of the problem went from the UI update. If you look at the queue_HandleMessage(MCHandleMessageEvent e) method, you can see that I try to show a Toast directly in. As you know, it's not possible, we must use runOnUiThread because only the main thread can update the UI.

2. I checked the queue's name on each side, I was making severals mistakes. It's OK now.

3. But (yes, there is a but), there's still something I don't understand on the server part. I made a lot of modifications, there's the code :

CLIENT
Code
public class MsgConnectClientActivity extends Activity {
   
   private MCUDPTransport transport = new MCUDPTransport();
   private MCMessenger messenger = new MCMessenger();
   private MCMessage message;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        MCMessenger.setLicenseKey("...");
                                                          
        transport.setMessenger(messenger);
      transport.setTransportMode(MCInetTransport.stmClient);
      transport.setActive(false);
      
      ((EditText)findViewById(R.id.port)).setText("14584");
      ((EditText)findViewById(R.id.address)).setText("10.10.1.196");
        ((TextView)findViewById(R.id.TextActive)).setText("Inactif");
        ((EditText)findViewById(R.id.EdtQueueName)).setText("SendDroid");
    }
    
    public void onButtonSendClick(View v) {
       
       String S = ((EditText)findViewById(R.id.EdtMessage)).getText().toString();
       String queueName = ((EditText)findViewById(R.id.EdtQueueName)).getText().toString();
        message = MCMessenger.createMessageFromText(1, 0, 0, S, null, false);
      
        String address = ((EditText)findViewById(R.id.address)).getText().toString();
        String port = ((EditText)findViewById(R.id.port)).getText().toString();
        
        address = "UDP:"+address+":"+port+"|"+queueName;
        Toast toast = Toast.makeText(getApplicationContext(), address, Toast.LENGTH_LONG);   
      toast.show();
        
        try {
         messenger.postMessage(address, message, null);
         toast = Toast.makeText(getApplicationContext(), "Message envoyé", Toast.LENGTH_LONG);   
         toast.show();
      } catch (EMCError e) {
         e.printStackTrace();
         toast = Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG);   
         toast.show();
      }
      
   }
    
    public void onActiveButtonClick(View v) {
              
       transport.setActive(!transport.getActive());       
       
       if(transport.getActive()) {
           ((TextView)findViewById(R.id.TextActive)).setText("Actif");         
       }
       else {
           ((TextView)findViewById(R.id.TextActive)).setText("Inactif");
       }
    }
}


SERVER
Code
public class MsgConnectServeurActivity extends Activity {
    
   private MCUDPTransport transport = new MCUDPTransport();
   private MCMessenger messenger = new MCMessenger();
   private MCQueue queue = new MCQueue();
   private java.util.Timer dispatchTimer = new java.util.Timer();
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        MCMessenger.setLicenseKey("...");
        
        transport.setMessenger(messenger);
      transport.setTransportMode(MCInetTransport.stmServer);
      transport.setMessengerPort(14584);
      transport.setActive(false);
      
        queue.setMessenger(messenger);
      queue.setQueueName("SendDroid");
        
      queue.addUnhandledMessageListener(new MCHandleMessageListener() {
         public boolean handleMessage(MCHandleMessageEvent e) {
            return queue_HandleMessage(e);
         }
      });
                        
      ((EditText)findViewById(R.id.EdtListeningPort)).setText("14584");      
      
      ((TextView)findViewById(R.id.TextActive)).setText("Inactif");
      ((EditText)findViewById(R.id.EdtListeningPort)).setEnabled(true);
      ((EditText)findViewById(R.id.EdtQueueName)).setEnabled(true);
      ((EditText)findViewById(R.id.EdtQueueName)).setText("SendDroid");
      
      //call dispatchMessage(), le timer sert à faire en sorte qu'on apelle cette méthode toutes les 1s (à peu près...)
      dispatchTimer.schedule(new DispatchTask(), 1000, 1000);
    }
    
    public void onButActiveClick(View v) {       
             
       int port = Integer.parseInt(((EditText)findViewById(R.id.EdtListeningPort)).getText().toString());
       
       if (!transport.getActive()) {         
         transport.setMessengerPort(port);
         transport.setActive(true);                  
      }
       else {
         transport.setActive(false);
         ((EditText)findViewById(R.id.EdtQueueName)).setEnabled(true);
       }
                
      if (transport.getActive()) {      
         ((EditText) findViewById(R.id.EdtListeningPort)).setEnabled(false);
         ((TextView)findViewById(R.id.TextActive)).setText("Actif");
         queue.setQueueName(((EditText)findViewById(R.id.EdtQueueName)).getText().toString());
         ((EditText)findViewById(R.id.EdtQueueName)).setEnabled(false);
      }
      else {
         ((EditText) findViewById(R.id.EdtListeningPort)).setEnabled(true);
         ((TextView)findViewById(R.id.TextActive)).setText("Inactif");
         ((EditText)findViewById(R.id.EdtQueueName)).setEnabled(true);
      }
    }
    
    //Calling when the incoming message occurred
     boolean queue_HandleMessage(MCHandleMessageEvent e) {
         
        boolean res = false;
        try {
           MCMessage message = e.getMessage();
           byte[] data = message.getData();
           
           if ((data != null) && (data.length > 0)) {

              runOnUiThread(new AsyncUIUpdate(new String(data)));             
              
              return true;
           }
           
        } catch (Exception ex) {
           String msg = ex.getMessage();
           if (msg != null) {
              ((TextView)findViewById(R.id.TextLog)).setText(msg);
              Log.i("DEBUG", msg);
           }
        }
        return res;
     }
     
     private class DispatchTask extends java.util.TimerTask {        
        
      public void run() {            
         if (transport.getActive()) {
            try {          
                messenger.dispatchMessages();
            } catch (Exception e) {
               e.printStackTrace();
            }
         }      
      }
   }
     
     private class AsyncUIUpdate implements Runnable {

        private String TextToShow;
        
        public AsyncUIUpdate(String tts) {
           TextToShow = tts;
        }
        
      @Override
      public void run() {
         ((TextView)findViewById(R.id.TextLog)).append(TextToShow + "\n");         
      }
        
     }
     
     /**
    * Evènement déclenché lorsque l'on clique sur un bouton du device.
    * Ici on teste si il s'agit du bouton "RETOUR", et on affiche une boite de dialogue demandant
    * à l'utilisateur de confirmer.
    * @param: int keyCode
    * @param: KeyEvent event
    */
   @Override
   public boolean onKeyDown(int keyCode, KeyEvent event) {
      if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {   
         this.finish();
      }
      else {
         return super.onKeyDown(keyCode, event);
      }
      return false;   
   }
}


The problem is on the onActiveButtonClick event. It's use to activate or desactivate the transport (and update the queue's name, for some tests). It works fine the first time, the transport activates. If I click once again on the button, it desactivates. Right.

But if re-click, nothing happens... I have to go on the Android's applications management and kill the process manually. It's doing the same thing when I restart. Do you know why ?


[ Download ]
#20026
Posted: 05/03/2012 03:49:24
by Eugene Mayevski (EldoS Corp.)

If the server is restarted immediately, it won't be able to bind the server socket. This is by design of TCP protocol. You need to wait for 2-3 minutes until restarting the server. On desktop there's an option to enable multiple binding (it also lets you avoid this 2-minute timeout) but the option doesn't seem to be available on Android.


Sincerely yours
Eugene Mayevski
#20027
Posted: 05/03/2012 04:10:33
by Nicolas Ciezki (Standard support level)
Joined: 04/26/2012
Posts: 13

It is the same thing for UDP protocol ? (Notice that now I use MCUDPTransport in my code)

Other thing : I haven't the problem on the client part, I can activate and desactivate the transport all the time.
Also by EldoS: BizCrypto
Components for BizTalk® and SQL Server® Integration Services that let you securely store and transfer information in your business automation solutions.

Reply

Statistics

Topic viewed 10565 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!