network and process_global variables issues

mc73

Well-Known Member
Licensed User
Longtime User
Hello,

I am facing two issues, mainly I suppose due to lack of knowledge by my side, so I would like your opinion/help on this:

The first issue has to do with sockets and asyncstreams. Whenever I want a communication to begin, I open a socket, then a asyncstream. That's ok, and it works great.
I'm closing the stream and the socket in activity_pause event, so

question 1: what happens with the corresponding objects at the server's side? From what I saw with logging, socket is closing, but the stream somehow seems to remain open, until the service module I use gets destroyed.

question 2: I remember in the beginning of my coding with netLib, I tried to close sockets and streams, whenever I thought that their job was done. Somehow, my job was not really done, thus closing the socket, didn't leave time for the streams to finish their operation (at least this is what I imagine). This is also the reason I placed the socket.close inside the activity_pause. My problem with that, is what will happen if my app crashes? I mean, would it pass from 'pause' or it would leave a socket open?

question 3: after taking Erel's precious advice, I came up to create a new socket every time I had a new connection with the server. At the same time, I had a new astream object. That's ok, but I had to do it like this:
B4X:
Sub Server_NewConnection (Successful As Boolean, NewSocket As Socket)
    If Successful Then
        Dim freeSocketId As Int
        freeSocketId=-1
        Dim k As Int
        k=-1
        Do While freeSocketId=-1 AND k<9
        k=k+1
        If socketsStatus(k)=0 Then
        socketsStatus(k)=1:freeSocketId=k
        socket1(freeSocketId)=NewSocket
        fSocket=freeSocketId
        End If
        Loop
       
        If freeSocketId=-1 Then
        freeSocketId=0
        socket1(freeSocketId)=NewSocket
        fSocket=freeSocketId
        End If
        aStreams(freeSocketId).InitializePrefix(socket1(freeSocketId).InputStream, False, socket1(freeSocketId).OutputStream, "AStreams" & freeSocketId)
   
    Else
        ToastMessageShow(LastException.Message, True)
    End If
    server.Listen
   
End Sub
This is my way to find a free-open socket, yet what puzzles me is more the new astream. The way I do it, I have to write code for every single new stream I want. I did this to an extent of 10 streams, but what if I need 100 different streams (100 connected devices)? Should I stick with writing that many astreams_newData, astreams_error? I believe I am missing something here, I would certainly prefer a dynamic array for this.

question 4: Occasionally, server loses its network connectivity (that's its own problem with wifi). What I noticed is that if I have an open socket with a stream, client is not getting a astreams_error, thus my app on the client side hangs. Sometimes, if server connects fast after its disconnection, streams continue, and my client continues to perform ok. It's just weird to me.

And a final question 5, irrelevant with networking:
Occasionally I experience wrong variable values when passing from an activity to another. These variables are dimmed in process_globals in my main activity, thus, I was hoping they would not get destroyed. I've read about activities' life cycle, still, I don't understand why a process_global variable, would lose its value. I know I can hold its value in a file, that's ok, but still this thing puzzles me, especially when I see an app crash because of a re-initialized variable (some of them take a 0-value time to time), while I know that this activity is in action almost all the time.

Any thoughts on these, would be really appreciated, thank you for your time.
 

mc73

Well-Known Member
Licensed User
Longtime User
oh and another one: android's sleep. though I am using a keep wifi alive and a network repairing tool, up to now this very bothering loss of communication seems inevitable.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Hi mc73,
I will just comment on the parts I understand.

Hello,
My problem with that, is what will happen if my app crashes? I mean, would it pass from 'pause' or it would leave a socket open?
On a crash Activity_Pause will not run. However all objects will be destroyed. Your socket object will get destroyed, I am assuming that will close your socket? Unless Ports retain states, I am not sure of this.

Occasionally I experience wrong variable values when passing from an activity to another. These variables are dimmed in process_globals in my main activity, thus, I was hoping they would not get destroyed. I've read about activities' life cycle, still, I don't understand why a process_global variable, would lose its value. I know I can hold its value in a file, that's ok, but still this thing puzzles me, especially when I see an app crash because of a re-initialized variable (some of them take a 0-value time to time), while I know that this activity is in action almost all the time.
Variables in Process_Globals should not get re-initialized unless the process is restarted. Something wrong is happening, could they be re-initialized else where?
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
Hi mc73,
I will just comment on the parts I understand.


On a crash Activity_Pause will not run. However all objects will be destroyed. Your socket object will get destroyed, I am assuming that will close your socket? Unless Ports retain states, I am not sure of this.


Variables in Process_Globals should not get re-initialized unless the process is restarted. Something wrong is happening, could they be re-initialized else where?
Thank you for your reply!

Yes, the socket object on the client side is destroyed, still sometimes in the log, I see the corresponding socket object on the server side alive! Oh, and when the server service module gets destroyed, what I see is all astreams objects getting destroyed, while I thought that closing them on the client side, and after I send a 'close' command to the server, I wouldn't face this.

Yes, this is also what I think, I mean, I've checked and rechecked whether I've mistakenly reset any variables of the main_activity in another activity, but I was just reading them. The only thought I did, was whether main activity is somehow restarted by the OS, and then setting wrong values. I'm really confused on this. Or perhaps, after a device wakes from sleep, tries to set the global variables to the current running activity, then it reloads the main activity, thus leaving me with wrong variables.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
Thank you for your reply!

Yes, the socket object on the client side is destroyed, still sometimes in the log, I see the corresponding socket object on the server side alive! Oh, and when the server service module gets destroyed, what I see is all astreams objects getting destroyed, while I thought that closing them on the client side, and after I send a 'close' command to the server, I wouldn't face this.

Yes, this is also what I think, I mean, I've checked and rechecked whether I've mistakenly reset any variables of the main_activity in another activity, but I was just reading them. The only thought I did, was whether main activity is somehow restarted by the OS, and then setting wrong values. I'm really confused on this. Or perhaps, after a device wakes from sleep, tries to set the global variables to the current running activity, then it reloads the main activity, thus leaving me with wrong variables.

I havent really worked with sockets and astreams so dont take my word on any of this. I'm just exploring and maybe I misunderstand many things.

So the server and client are both B4A apps. I expect the server socket to remain alive unless it is closed explicitly. Although Connected should then be False. After all its the server so it should keep listening for anyone connecting.
On the server side, when the service is destroyed, the astreams at the server side get destroyed too? It looks reasonable behaviour to me. Afterall there is nothing to listen to anymore.

Regarding Process Global variables. Are you saying this behaviour happens only on sleep or pause/resume?
I think when the device goes into sleep pretty much the process gets killed. When you resume it, you dont go through the main activity that sets up those variables?
If you only set those variables in the main activity you will get this problem. If possible set them up within Process_Globals and use a default value for e.g. '0' to know that they are initialized. or a flag like varsUpdatd = True. (by default it would be False).
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
I havent really worked with sockets and astreams so dont take my word on any of this. I'm just exploring and maybe I misunderstand many things.

So the server and client are both B4A apps. I expect the server socket to remain alive unless it is closed explicitly. Although Connected should then be False. After all its the server so it should keep listening for anyone connecting.
On the server side, when the service is destroyed, the astreams at the server side get destroyed too? It looks reasonable behaviour to me. Afterall there is nothing to listen to anymore.

Regarding Process Global variables. Are you saying this behaviour happens only on sleep or pause/resume?
I think when the device goes into sleep pretty much the process gets killed. When you resume it, you dont go through the main activity that sets up those variables?
If you only set those variables in the main activity you will get this problem. If possible set them up within Process_Globals and use a default value for e.g. '0' to know that they are initialized. or a flag like varsUpdatd = True. (by default it would be False).

thank you once again.
the server temporary sockets and their corresponding streams are closed, I take care of this, by sending a command from the client. it's just when service get destroyed that I've noticed streams getting destroyed, and that's kind of wierd since I thought I've already closed them.
your second note is what I was afraid of. I was hoping I shouldn't have to set the global variables again. why? they're just too many :(
by the way, did you notice how I setup astreams? any idea if we can make it with just an array?
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
thank you once again.
the server temporary sockets and their corresponding streams are closed, I take care of this, by sending a command from the client. it's just when service get destroyed that I've noticed streams getting destroyed, and that's kind of wierd since I thought I've already closed them.
your second note is what I was afraid of. I was hoping I shouldn't have to set the global variables again. why? they're just too many :(
by the way, did you notice how I setup astreams? any idea if we can make it with just an array?
Closing the Astreams will probably not destroy the astream object (because they may be re-used). I think to destroy them you will have to do something like varAstream = Null. Although I am not sure.

Well, thats how Process_Globals work. They remain alive till the process stays alive. The alternative could be to write them to a file. Or lump as many together as you can.

While I dont completely understand your code, I see you are looking for a free socket between 0 to 9 and a corresponding async stream? And socketstatus gets updated elsewhere when the connection is released?
While your solution is also good. You can tie a socket with an astream with a custom type or a map.
Map1.Put(socket,astream)

Looking for a free socket is more dynamic, so your solution looks better to me. Unless you use a list which could be more scalable. Also could you just use Socket.Connected to see the status rather than use socketstatus?
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
I answer your last one. Seeing an earlier bug in socket.connected (I think this is not a bug any more, but at the time of writing, I didn't check this), I used this socketStatus flag just to be sure.
Yes, the socketStatus is updated in a closeSocket subroutine, where I close the socket and its corresponding aStream. I still use arrays instead of maps, since I'm more familiar with them, from my other programming tools.

About process_globals, now. I absolutely agree with you, but what I don't understand is how on earth is the process destroyed, since I see on my device the screen of whichever activity is on. I mean, the activity is not destroyed, thus why are the global variables destroyed? Anyway, I think I cannot do much on this, I will just have to write all variables in a temporary file waiting for an activity_resume event.
So, I can set astreams to null? If this is the way, like we set objects to nothing, in other languages, I will certainly try it, thank you!
Still, my question about 100 (ok, that's just a number) sockets, remains. I cannot imagine having to write 100 identical routines, namely astreams0_newdata up to astreams99_newdata. I feel there is an answer which I don't see it now, yet, this will not be the first time, I oversee something :)
 
Upvote 0
Top