Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
ubuntaur
Posts: 41
Registered: ‎09-11-2009
My Device: Not Specified
Accepted Solution

Problem Testing Signal Before Using TCP Connection

Right now my app uses a TCP SocketConnection to communicate with a remote server.  This works fine, but I'm trying to make sure my program can gracefully handle the situation of moving to an area with no coverage.

 

When I run my app, if I uncheck the "In coverage" checkbox for GSM and CDMA under network properties, my app does fine until it calls the OutputStreamWriter.write() function to send something over the socket connection.  I have it within a try/catch block, but it just seems to hang instead of throwing an exception.

 

How can I check the signal before trying to send data over the SocketConnection?

 

To help clear things up, here is the order of what's happening:

 

1. App starts while in coverage.

2. SocketConnection is made successfully.

3. OutputStreamWriter is made from SocketConnection successfully.

4. Coverage is lost

5. OutputStreamWriter.write() is called, but hangs instead of throwing an exception.

Developer
peter_strange
Posts: 19,610
Registered: ‎07-14-2008
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

Never had a socket hang on a write, at least not that I am aware of.  It usually hangs on the following read, and eventually times out.  Does your write time out?  Are you seeing this on the Simulator or the Device?  What OS levels are involved.

Developer
ubuntaur
Posts: 41
Registered: ‎09-11-2009
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

Mine does not seem to time out.  It will just hang indefinitely or freeze the app (only when I tested it from the gui thread just to try a different thread).  I am running on a 9530 simulator with OS 4.7.0.75.

 

The app keeps to itself except for some settings which are saved via persistent storage. I have one thread that is continuously reading from the socket, but it checks first to see if the IinputStreamReader is ready to be read from (thus no timing out whenever the signal is lost). Then I have another thread which is checking a runtime store for any outgoing messages that need to be sent.  It runs until it calls this function:

 

 

 

//sends a string
public void send(String s) throws IOException{
    writer.write(s, 0, s.length());
}

 

When I have the default CMDA Network enabled, this runs fine.  When disabled, it just gets stuck.

 

Would calling RadioInfo.isDataServiceOperational() be a safe way to determine whether or not it is safe to call my send() method?

 

 

Developer
peter_strange
Posts: 19,610
Registered: ‎07-14-2008
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

I guess you understand the problem of freezing the app when calling on the Event Thread, so I won't talk about that.

 

I don't keep a socket open, I open, send or receive, then close.  I've always thought that keeping a socket open was not a good thing. 

 

The only thing I would say is that I do not send and receive at the same time on the same socket connection.  So instead of having one Thread reading and another writing, I have one Thread that reads and writes - flip/flops according to a agreed protocol with the Server. 

 

I'm confused about this statement:

"checks first to see if the InputStreamReader is ready to be read from"

How do you do this check?

 

I would recommend using RadioInfo.isDataServiceOperational() before doing any activity, but I'm not sure it is all you need in this case.  I presume that your InputStream will give an exception if there is a lose of network.  I would have thought at that time it would be appropriate to can the send Stream off as well, and re-instate it when the network is back.  So your sends should remain queued.

 

BTW, is RuntimeStore a good place for your send messages?  In our case, the data to be sent is persisted, to make sure that it will be sent should the device get rebooted, or battery taken out.

Developer
ubuntaur
Posts: 41
Registered: ‎09-11-2009
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

Yes, I learned the hard way not to do any I/O on the Event Thread :smileywink:

 

I agree, I think having one thread for reading/writing would be a better idea.  As for my socket, I plan on keeping the same one open until the connection is lost.  Once I regain a signal I will reconnect with a new socket.  

 

Now I understand how you could open a socket, send data, then close the socket, but with my company's software, information from the server can come at any time, so how do you know there is data to be read if you don't keep the socket open? Are you saying that I can open a socket, create an InputStreamReader and OutputStreamWriter, close the socket, and then continue using the streams made from the socket (which is now closed)?

 

InputStreamReader has a function called ready() that lets you know if there is any data to be read from the stream.  I call InputStreamReader.ready() before ever reading anything from it.

 

I've started to implement RadioInfo.isDataServiceOperational() into my code and so far it's working out exactly how I want it to.  The only connection I'll be making is a SocketConnection (and I/O streams form this socket), so as long as this function tells me when I am able to receive/send data then I guess I'm good to go.

 

Also, I see you point regarding storing my outgoing queue in persistent storage instead of runtimestore.  I will make that change as well.

Developer
peter_strange
Posts: 19,610
Registered: ‎07-14-2008
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

"Now I understand how you could open a socket, send data, then close the socket, but with my company's software, information from the server can come at any time, so how do you know there is data to be read if you don't keep the socket open?"

 

It is called PUSH.

 

I am lucky, in that the socket level communication I have been telling you about has been developed for the corporate market and BES Push has been there as long as I have been coding for BB's. 

 

For consumer apps, there was, till now, nothing, so you basically had to do what you are doing (which to be honest, I'm not sure works), or poll.  To do what you are doing I would have thought would require some sort of heart beat, and is expensive in terms of battery usage.  Polling uses less battery, but of cause introduces a delay and there is potential for a lot of wasted polls (increasing battery usage and data charges).

 

The other alternatives were SMS, or email transmissions to alert the processing on the Blackberry that there was data ready.  In fact I believe the email method worked quite well

 

But RIM recently announced BIS push, and at DevCon announced it would be free to use, at least for the first year.  I believe there are beta testers for it now.  There is information for it around, including some forum entries, but the best place to start is here:

 

http://na.blackberry.com/eng/developers/javaappdev/pushapi.jsp

 

It might be that you have to have some sort of paid for Alliance membership to sue this - I'm not sure.

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

Socket connection's output stream write operations not throwing an exception when there's no coverage is the correct behavior. This is because on cellular networks the IP tunnel to the carrier (and hence the TCP connections over this tunnel) survives loss of coverage. For example, if your app opens a TCP connection from a BlackBerry, then the BlackBerry loses coverage, then regains coverage, say, 1 minute later, the TCP connection opened by your app will continue working fine, unless your server or some intermediate network component closes the connection due to inactivity.
Developer
peter_strange
Posts: 19,610
Registered: ‎07-14-2008
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

That is really interesting and not something I would have thought happens.  Thanks for passing this information on.

 

Does this means that the output socket connections will be 'held' regardless of the connectivity option (WAP 2, direct TCP or BIS-B especially) used?

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

[ Edited ]

That's due to mobility management offered by cellular networks. In theory this should apply to all packet-switched communications over cellular networks. This would imply that WAP 2, Direct TCP, BIS-B, and MDS connections should survive losses of coverage, unless the server-side times them out while the device is out of coverage. I have only confirmed this for Direct TCP though.

Developer
ubuntaur
Posts: 41
Registered: ‎09-11-2009
My Device: Not Specified

Re: Problem Testing Signal Before Using TCP Connection

Very interesting indeed.  

 

Thanks for the help guys!