Android Question How do I poll a socket until connected ?

emockler

Member
Licensed User
Longtime User
Sub VNC
Dim Intent2 As Intent
Dim pm As PackageManager
Intent2 = pm.GetApplicationIntent ("com.iiordanov.bVNC")
Intent2.Initialize("android.intent.action.MAIN", "vnc://192.168.1.111:5988")
Intent2.SetComponent("com.iiordanov.bVNC/.RemoteCanvasActivity")
StartActivity (Intent2)



End Sub

Sub Socket1_Connected(Connected As Boolean)As Boolean
If Connected = True Then
VNC
Return True
Else
Return False
End If



End Sub
 

Lee Gillie CCP

Active Member
Licensed User
Longtime User
In design/approach I would not poll for anything. Avoid polling like the plague. You don't need it anyway. Instead I would use the events to drive the activity, such as the Connected EVENT (not to be confused with the the Connected PROPERTY). HTH
 
Upvote 0

emockler

Member
Licensed User
Longtime User
Thanks for the reply Lee, but I see half my question is gone. How would I wait for the connected event? If you have an example I can understand your answer better.




Well, I typed up a question re jkSSH2, then figured it out before submitting. Typed a new question, under the wrong jkSSH2 title. Edited that one to say "please delete". I started over with this title and I thought I copied the text to this new correctly titled question, but I guess not. So I see it doesn't make a lot of sense.

The most important part of my question is missing, where I say I've been working with B4A for 3 days (4 now). So I went through the beginner's guide to the point of making buttons, just to flesh out the basic requirements. Then I look for examples & other users questions to find code that could be adapted for what I want to do. I bought it a few years ago, but at the time it looked too hard to learn so I went back to AI. That was ok, since I used SL4A to make up for it's limitations. But now I writing this for Android X86 kitkat, and SL4A does not work. So I'm trying B4A and finding it not as hard as I thought it would be.


I'm trying to start a VM on an ESXi server with SSH. This works
Then I launch VNC to the VM. But it can be sometimes up to 1 min or more after sending the power.on before the VNC port is actually available. So I want to avoid any "can't connect" error, I want to check if the port is open first before launching VNC.

I'm using Sockets to check if the port is open, if it returns true it launches VNC. But it only does it once, and sometimes fails. I want it to wait until the port is open and then launch VNC.

Here's my code again: (Please remember I pieced this together from examples & other questions, so I could be WAY off)

Sub Button6_Click
'Dim Intent2 As Intent
'Dim pm As PackageManager
Dim Socket88 As Socket
'Dim Socket1_Connected As Boolean
SSH2.initialize("SSH", "192.168.1.111", 22)
user = "root"
password = "password"
myKey = File.ReadString(File.DirAssets, "ssh-cert.pem")
DisableStrictMode
SSH2.authenticateWithKey(user,myKey, password)
SSH2.execCommand("vim-cmd vmsvc/power.on 88", 10)


Socket88.Initialize("Socket88")
Socket88.Connect("192.168.1.111", 5988 , 3000 )

End Sub

Sub VNC88
Dim Intent2 As Intent
Dim pm As PackageManager
Intent2 = pm.GetApplicationIntent ("com.iiordanov.bVNC")
Intent2.Initialize("android.intent.action.MAIN", "vnc://192.168.1.111:5988")
Intent2.SetComponent("com.iiordanov.bVNC/.RemoteCanvasActivity")
StartActivity (Intent2)


End Sub

Sub Socket88_Connected(Connected As Boolean)As Boolean
Dim Socket88 As Socket


If Connected = True Then
VNC88
'Wait (15)
iommu
'KillVNC
Return True
Else
Socket88.Initialize("Socket88")
Socket88.Connect("192.168.1.111", 5988 , 3000 )

Return False
End If

End Sub
 
Upvote 0

Lee Gillie CCP

Active Member
Licensed User
Longtime User
The fundamental issue is that you want to avoid blocking the main GUI thread waiting for something to happen. You might show a "working" pop-up while waiting. And then we are guided to do all network access off the main GUI thread. So when you get the result of a network activity, then actually updating the screen must be marshalled back to the main thread.

Remember, the Connected EVENT will fire regardless of connection success or failure. Use an appropriately long timeout parameter on the call to connect. Decide to do your VNC stuff perhaps in the Connected event handler, based upon success or failure of the connection. If failure, what then? This can also dispatch that, which might be a pop-up, stop a "waiting to connect..." pop-up, etc. But otherwise, you want to free the user to utilize your GUI while waiting for this, or intentionally be modal, with a limit for how long you decide you are willing to lock up the user.
 
Upvote 0

emockler

Member
Licensed User
Longtime User
The user would push the button to power on the VM. He is then essentially done with the APP, and waiting to use the VM he powered on. The machine has 6 video cards, all passed through to VM's using PCI Passthrough. 1 is passed through to an Android x86 VM that runs at boot and displays this app I'm writing.

Normally the user would be done, and just waiting for the VM to come up. Occasionally the VM may be stuck in "startup repair", and the user would need the VNC access since the GPU used would be the VMware Svga. I will also be adding an option to boot to BIOS which would also need VNC. Or installing a new VM I would need VNC for txt mode.

Usually the VM powers up fast enough to be within the VNC timeout and all is OK. But if there are many snapshots the VM can take minutes to boot. But, the user just has to wait and I don't need anything available. Now that I think of it, I guess a progress bar or at least some feedback that the power.on was successfully sent and is in progress would probably be good. I intend to eventually change the TXT on the button to green from red to show state, but power.getstate doesn't return ON until it's all the way on.

On AI2 I used SL4A which could run background scripts, so I would use that to make up for AI2's limitations. I checked the port with netcat & the script would just sit until the port was open, then launch VNC. Then it would tail the VMkernel.log for the event that activates the passed through GPU, and Kill VNC. This was all in the background, so it was a nice interface.

This is for FREE ESXi, so I have to use SSH rather than any VMware API's.

I would like to loop around checking the connection, display "please wait" if not ready, check again, etc and when ready launch VNC, unless 5 min goes by then BAIL. I've been trying some things, but I'm confused since the example I found has stuff regarding the socket under 2 subs, and I don't know how to get it to check the socket repeatedly.

Thanks!
 
Upvote 0

Lee Gillie CCP

Active Member
Licensed User
Longtime User
Why not:
  1. Display "Connecting..."
  2. Initiate socket connection with 5 minute timeout
  3. Upon Connected event:
    1. Hide "Connecting..."
    2. If success:
      1. Launch VNC
      2. Exit
    3. If failure
      1. Bail
You don't state what you are doing in the loop of connect tests. If you REALLY need it, in step 1 you could note the time, or attempt count, use a smaller connect timeout, retry another connect attempt for the short period if not enough time or tries count to bail yet. This uses a good asynchronous model, which won't block the GUI, to implement polling like capabilities. But without seeing the need for the additional complexity, why have it? It won't check or attempt repeatedly by itself. The connect timeout parameter is your friend!

Perhaps you are saying it fails quickly when it fails? If so, the idea of calling CONNECT again, throttled by the timestamp you take in step 1 will allow you to continue to try for 5 minutes, even though the connect attempt failures happen quickly.
 
Upvote 0

emockler

Member
Licensed User
Longtime User
Is this where I set the timeout?

these lines are under the button click sub:

Socket88.Initialize("Socket88")
Socket88.Connect("192.168.1.111", 5988 , 3000 ) <--change the 3000 to 60000 ?



then I have this also:

Sub Socket93_Connected(Connected As Boolean)As Boolean <---
Dim Socket93 As Socket
If Connected = True Then
VNC93
Return True
Else
Socket93.Initialize("Socket93")
Socket93.Connect("192.168.1.111", 5993 ,3000 ) <---- I put this here again to try again. It doesn't work without this for some reason.

Return False
End If

Thanks again!
 
Upvote 0
Top