I managed to programm an app that communicates with a server. I can write and I can read. I even managed to do it with Java NIO.
My problem is that I have a endless while loop that is listening for new data to read. It blocks the whole program and I can't write anymore data.
I need a solution so the loop keeps running in background listening for new data to read while I send data.
Any suggestions?
Use AsyncTask. It was created just for this kind of jobs (doing long running background tasks, while still have a possibility to update UI).
You could either create a separate thread to handle the socket asynchronously and pass messages through a handler, or create a local service to handle the comms.
You should never do a long wait on the main (UI) thread.
If your loop is blocking the whole program there is something wrong with it. I don't see what other answer you can realistically expect until you post some code.
Related
Hi guys am getting following error am using Websocket and Tomcat8.
java.lang.IllegalStateException: The remote endpoint was in state [TEXT_FULL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1092)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textStart(WsRemoteEndpointImplBase.java:1055)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendString(WsRemoteEndpointImplBase.java:186)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:37)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet.broadcastData(IRIMonitorSocketServlet.java:369)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet.access$0(IRIMonitorSocketServlet.java:356)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet$5.run(IRIMonitorSocketServlet.java:279)
You are trying to write to a websocket that is not in a ready state. The websocket is currently in writing mode and you are trying to write another message to that websocket which raises an error. Using an async write or as not such good practice a sleep can prevent this from happening. This error is also normally raised when a websocket program is not thread safe.
Neither async or sleep can help.
The key problem is the send-method can not be called concurrently.
So it's just about concurrency, you can use locks or some other thing. Here is how I handle it.
In fact, I write a actor to wrap the socketSession. It will produce an event when the send-method is called. Each actor will be registered in an Looper which contains a work thread and an event queue. Meanwhile the work thread keeps sending message.
So, I will use the sync-send method inside, the actor model will make sure about the concurrency.
The key problem now is about the number of Looper. You know, you can't make neither too much or too few threads. But you can still estimate a number by your business cases, and keep adjusting it.
it is actually not a concurrency issue, you will have the same error in a single-threaded environment. It is about asynchronous calls that must not overlap.
You should use session.get**Basic**Remote().sendText instead of session.get**Async**Remote().sendText() to avoid this problem. Should not be an issue as long as the amount of data you are writing stays reasonable small.
I want to generate some text string that is going to be sent via TCP socket . I have accomplished it within few minutes.
However I want a producer consumer pattern.I dont care if it failed or not.
Should I create a Blocking Queque at application for this ? Should I create a service ?
Note that I want a single thread to manage this job.
In the case it's a short task (like you commented), I'd recommend putting it within an AsyncTask as a background thread. You can control anything about this separately, which will help you also debugging it. Services are more intended for long executing tasks, so I'd not recommend it at this scope (it's a bit harder even to communicate with other Activity's. Here you'll find the AsyncTask's documentation, and here a good example.
The Blocking structure depends on your needs - but I don't think you'll need that in your case. Anyway, if you would need that, there're lots of thread-safe data structures you may use, you might find this helpful.
Create a LinkedBlockingQueue where your producer adds data. Create a Timer that fires every second or so. The task of the Timer would be to send the messages over the wire.
For this, both the producer (the one generating the messages) and consumer (Timer) should have access to the LinkedBlockingQueue. The Timer will remove the first element of the LinkedBlockingQueue and then send it.
Sounds good ?
For this school assignment, I need to simulate a client server type application using Java threads (no need for sockets etc). How might I go about doing it?
I need a way to server to start and wait for clients to call it then it should return a response. The "API" in my mind was something like:
server.start()
client1.connect(server)
client2.connect(server)
x = client1.getData()
y = client2.getData()
success1 = client1.sendData(1)
success2 = client2.sendData(2)
How might the server|client.run method look like? Assume I could hardcode the method calls for now.
I suggest to use the following approach:
1. Have "server" code that works with Blocking Queue -
A blocking queue is a data structure which is synchronized and let's the thread that reads data from it (the "consumer" thread) to wait until there is a data in the queue to be read.
The "producer" thread is a thread that "pushes" data on the queue.
I would recommend you use one of the blocking queue implementations.
I would also suggest you read more about "consumer producer" pattern.
Blocking queue also eliminates the need for "busy wait" which is not recommended in multi-threading programming.
From the description that you have provided What i can suggest is you should write some thing like
1) Have one queue where all the clients can put up messages.
2) server which is running in an infinite loop like while(true) waits for the new messages that has been put in the queue and if it finds one then processes it and marks it as processed.
3) The job of the client threads would be to create messages and put them in the queue. And notifying the server that new message has been added to the queue so that server can come to know that new message has been arrived for processing.
For this program to make it working i think you need to learn Thread's notify, notifyAll(), and wait() methods. So basically without sockets what you are looking for it "Inter thread communication". This link can help.
Hope this helps.
I have implemented an service that runs in a seperate process.
This service contains a separate thread where i have a socket connection.
This thread has a run() where it is continuously sending data to the port.
My problem is after triggering the run() in the thread i don't get any contact with it anymore, i can see in the program that have open the socket that it consciously sends the data but the idea was that i while it is running i could change data that it sends for an example time.
here is my run in the external thread:
public void run()
{
if(run)
{
// Team and player names message is sent when entering in a game
setBaseMessage();
SendMessageToCOMPort(base_message + CalculateCRC(base_message));
sleep(); // waits for 100 ms
}
}
Anyone have any idea what might be wrong ?
I did not quite get your problem. It seems that you want to run a separate thread in your service which does some socket communication. Furthermore you want to be able to influence the data the thread is sending using the socket.
I have implemented an service that runs in a seperate process.
First of all, android services aren't running in a separate process or thread by default. Therefore, to run long running operations you have to develop multithreading by your self using Java threading and implementing the run method as you have done it.
Threads of a single process share the same memory. Therefore, to influence what the socket thread is doing, you can use data structures like a queue or a list which are shared among the threads. For example, you could apply the producer-consumer pattern. The producer passes data to a shared queue. The consumer consumes the data from the queue and processes it. However, be aware that you have to synchronize the access to the shared queue.
I hope I was able to clarify the issue and give you some advice to solve the issue.
Is there any possibility to communicate with clients by events? I mean:
I have connected client, InputStreamReader and PrintWriter
in = new BufferedReader(new InputStreamReader(
client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
when I use in.readLine() server waits for incoming data. But i have this situation:
Client didn't send any data
Connection is still alive
I need to send some data to client (but in.readLine() is still hanging process) and wait for respond
The questions are:
What is the best way to handle asynchronously incoming data? I mean something like "events". Should I create thread for read and another thread for write? If i can do it in one thread, could you give an example of the code please?
Is possible to abort waiting for in.readLine()?
Java provides non-blocking i/o through the java.nio package (see here). But Java's "nio" channels do not inter-operate with streams from java.io. So, if you want to use nio, you'll have to build your server with nio from the listener on down.
If you're stuck with the existing java.io streams, then you'll either have to use a thread-per-client model; or you'll need to devise a system for having a single thread (or pool of threads) manage a bunch of clients by looping over them repeatedly, polling instream.available() to figure out which ones have data ready to be handled. Of course, in this latter case, you'd want to avoid busy-looping, so some appropriate use of Thread.sleep is probably also in-order.
In my opinion having a separate thread to perform socket IO is best if you want your program to behave asynchronously. Have a look at http://en.wikipedia.org/wiki/Observer_pattern.
For a simple application, what I'll do is create a separate thread to listen for incoming data, and register 'observers' or 'event listener' to this thread. When a data comes in, notify your observers so they can perform necessary actions.
While the listener thread is idle waiting for data, your main thread still can progress normally.
Make sure you're also familiar with Java concurrency programming