I'm developing a multithreaded web server for an android app and I've some problems with a page that uses an external .css file, and a .js file, but only with Google Chrome! With Firefox and Opera the page is rendered fine, with Google Chrome sometimes the .css is loaded, sometimes the .js, sometime both or neither.
This is my app's structure:
WebServer.java
class WebServer implements Runnable{
protected boolean ON;
public void start(){
if(!ON){
ON=true;
thread=new Thread(this,"WebServer");
thread.start(); }}
public void run(){
while(ON){
listenSocket = new ServerSocket(port);
Socket connectionSocket = listenSocket.accept();
Thread t = new Thread(new Client(connectionSocket));
t.start();
listenSocket.close();}
}}
Client.java
class Client implements Runnable {
public void start(){
thread=new Thread(this,"Client");
thread.start();}
public void run(){
//parse the request and send a file
}
}
myApp.java
public class myApp extends Activity{
onCreate(){
WebServer ws=new WebServer(8080);
}
onClick(){
...
ws.start();
}}
When I click a button on the activity, it call webserver.start(); In my opinion google chrome sends more requests concurrently and there's a problem with threads...
Can you help me?
[EDIT]
I had forgotten to write the loop in the run() method in the question
[EDIT 2]
I just tried with an other pc, and there are problems also with firefox..
There is a general misunderstanding of the thread mechanism in your code.
A runnable has to override run. Not start. The run() method of the runnable will be called when the nesting thread will be started. In other words, the start method of your client will never be used, and hope fully, as it would create a thread inside a thread.. not very usefull.
Redesign your webser so that, :
it's start method starts a new nesting thread as you did
it's run method does the following
your webserver binds to a port
in a loop : accept new connections and start new client thread for each.
the loop could be controlled by a boolean flag that you could rise to stop the server (ON would fit, even if the name of this variable doesn't follow java naming conventions and is rather poor semanticly speaking)
then each client would, in it's run (no more start method) :
read data from socket input stream
reply on socket outputstream
briefly, implement http protocole.
You could find some java code to inspire you on the web, some examples are well documented. Also, you could consider using java.nio package that is maybe less effective for a single request but much more effective at handling massive multiple connections. But code is harder.
You should consider reading more about runnables and also consider reading some stuff about synchronized key word to ensure that your web server doesn't start twice a connection for the same client or get confused in case of simultaneous requests.
Regards,
Stéphane
Related
So if I have a socket server, I can accept each socket and pass it to a executory
while(true){
Socket conn = socketServ.accept();
Runnable task = new Runnable() {
#Override
public void run() {
try{
server.executor(conn);
} catch(IOException e){
}
}
};
exec1.execute(task);
}
Doing this allows my server to run on my threads and does not block the same thread. Because I also have reference to that socket... called "conn" I can successfully return messages as well.
Now I have an RMI interface, which basically lets me call methods back and forth.
for example if I had this method:
public MusicServerResponseImpl CreatePlayerlist(String Name, UserObjectImpl uo) throws RemoteException {
MusicServerResponseImpl res = new MusicServerResponseImpl();
return res;
}
Which returns a serializable object. My concern is when this message gets called, I think it is going to get called in the main thread of the server, and thus will block that thread and slow down parallelism.
What I think is the solution is to have every single RMI method also create a task for an executor.. to speed up the execution of everything...this issue I am seeing however is unlike the socket where I have an object to send information back to, I am unsure how I would return a response from the RMI method, without somehow having to block the thread.
Does that make sense? Basically I am asking how I can execute in parallel with RMI methods while still being able to return results!
Thanks for the help!
Does that make sense?
No. Concurrent calls are natively supported.
See this documentation page and look for the property named maxConnectionThreads.
You could also have tested your assumptions by, for example, printing the current thread name in your server code, and trying to execute concurrent calls and see what happens.
Kind of a "noob" problem here.
I have a small application to write (like a simple game). There is server-side and client-side. It has to use websockets as the way of communication. Server has a server class (with main() that starts the server) as well as server endpoint class. However, the game is not turn based, but real time based. So the server has to do certain computations every "tick" b/c of the dynamic field.
I assume that Threads would suit well in this case, but I don't know how to put threads with this kind of server.
As I can see, the only thing that can receive/send messages is endpoint. If I make it implement Runnable and pause every 0.5 of a sec, it won't accept messages during that pause time. If I define a different class for that purpose, I have no idea how I start it inside of an endpoint and make a way for them to communicate.
Does anyone have any suggestions/info/links/anything that may help?
Thank you in advance.
Server endpoint will continuously receive data from client side. All you have to do is to process that data in some other thread. You can define a different class for that purpose (a thread). This thread class will have two different queues.
In queue - to receive data from the endpoint
Out queue - to send data to the endpoint
(You can use ConcurrentLinkedQueue for that. more help -> How to use ConcurrentLinkedQueue?)
Start this processing thread inside the endpoint. when endpoint receives data, put them into the In Queue. Continuously listen to the Out Queue and send that data again to the client side.
Endpoint code
#OnMessage
public void onMessage(String message,Session peer) throws IOException{
processingThread t = new processThread(peer);
t.inQueue.add(data);
t.start();
String s;
//listen to the Out Queue
while (true) {
while ((s =t.outQueue.poll()) != null) {
peer.getBasicRemote.sendText(dataToBeSent);
}
}
}
processingThread Code
public class processingThread extends Thread{
public ConcurrentLinkedQueue<String> inQueue = new ConcurrentLinkedQueue<String>();
public ConcurrentLinkedQueue<String> outQueue = new ConcurrentLinkedQueue<String>();
public void run(){
//listen to in queue and process
//after processing put to the out queue
}
}
Hope this will help :)
I try to get a connection to multiple clients using the Sockets in Java. Everything seems to work, but the problem is, that the server just listens to the first client. If there are multiple clients, the server can send them all messages, but he can just listen to the messages that came from the first client. I tried this all out (I'm at this problem since yesterday). So I'm pretty sure, that the fault has to be in the class "ClientListener".
Explanation:
There is a List with clients (connection to communicate with Strings). In the GUI there is a list, where I can choose, with which client I'd like to communicate. If I change the client, the variable currentClient (int) switches to another number
networkClients is an ArrayList, where all the different connections are "stored".
The first connected client is exactly the same as the other clients, there is nothing special about him. He is called, when the variable currentClient is set to 0 (per default). The variable-switching is working. Like I said, all the clients give me a response if I send them an order, but just networkClients.get(0) is heard by the server (ClientListener).
class ClientListener implements Runnable {
String request;
#Override
public void run() {
try {
while (networkClients.size() < 1) {
Thread.sleep(1000);
}
//***I'm pretty sure, that the problem is in this line
while ((request = networkClients.get(currentClient).getCommunicationReader().readLine()) != null) {
//***
myFileList.add(new MyFile(request));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
I hope someone can help me. I tried many things, but nothing worked.
EDIT: Like I wrote in the code example, is it possible that the while-loop isn't able to switch the number of "currentClient" (which is handled by another Thread)? I tested/simulated something similar in a testclass and the result was, that a while-loop of course can can update the state in it (meaning, that if a variable changes in the () of a while loop, it will of course be checked after every repeat).
You should take a look at multithreading.
Your server program should be made out of:
- The main thread
- A thread that handles new connections.
(Upon creating a new connection, start a new thread and pass the connection on to that thread)
- A thread for each connected client, listening to the each client separately
Take a look at some examples like: (1) (2)
I found the solution:
The Thread sits in the declared method I mentioned in the starting post (in the code snippet) and waits unlimited time for a new response of the client.
So changing the index of the list "networkClients" won't do anything, because nothing will happen there, until there is a new order sent by the client (which lets the thread go further).
So you need to implement an extra listener for each client.
On my Android App, I'm implementing SignalR connection (https://github.com/erizet/SignalA) to connect to a Hub server to send requests and receive responses.
a sample of my code is as follows:
signalAConnection = new com.zsoft.SignalA.Connection(Constants.getHubUrl(), this, new LongPollingTransport())
{
#Override
public void OnError(Exception exception)
{
}
#Override
public void OnMessage(String message)
{
}
#Override
public void OnStateChanged(StateBase oldState, StateBase newState)
{
}
};
if (signalAConnection != null)
signalAConnection.Start();
There's also the sending bit
signalAConnection.Send(hubMessageJson, new SendCallback()
{
public void OnError(Exception ex)
{
}
public void OnSent(CharSequence message)
{
}
});
The sending and receiving will occur across activites, and some responses will be sent at random times regardless of the activity, also, the connection should be opened as long as the app is running (even if the app is running in the background) that's why I wish to implement the signalA connection as a background service
The question is should I implement it as:
1 - a Service (http://developer.android.com/reference/android/app/Service.html)
OR
2 - an Intent Service (http://developer.android.com/training/run-background-service/create-service.html)
Keeping in mind that I will need to send strings to the service and get response strings from the service.
I would be most grateful if someone would show me how to implement this kind of connection in code as a background service/intentservice.
Thanks for reading.
UPDATE:
Please see this demo activity made by the developer as how he implemented SignalA
https://github.com/erizet/SignalA/blob/master/Demo/src/com/zsoft/SignalADemo/DemoActivity.java
The problem is AQuery (which I know nothing about) is being used in this demo activity. Does AQuery run in the background all the time ?
The problem is, the latest update on SignalA mentions the following
I have changed the transport. LongPolling now uses basic-http-client
instead of Aquery for http communication. I've removed all
dependencies on Aquery.
Hence I'm not sure whether I should follow this demo activity or not
Update 2:
This is the thing that is confusing me most
in the IntentService, the OnHandleIntent method calls stopSelf after it finishes its tasks, when I actually want the code in the IntentService to keep running all the time
protected abstract void onHandleIntent (Intent intent)
Added in API level 3
This method is invoked on the worker thread with a request to process. Only one Intent is processed at a time, but the processing happens on a worker thread that runs independently from other application logic. So, if this code takes a long time, it will hold up other requests to the same IntentService, but it will not hold up anything else. When all requests have been handled, the IntentService stops itself, so you should not call stopSelf().
SignalA is running on the thread that creates and starts the connection, but all network access is done in the background. The remaining work on the starting thread is really lightweight, hence its perfectly ok to do it on the UI tread.
To answer your question, you need to have a thread running the signala connection. Therefore I think a Service is the best choice since SignalA need to be running all the time.
Regarding Aquery and the demo project. I removed all dependencies to Aquery in the libraries, not in the Demo. To be clear, you don't need Aquery to run SignalA.
In my case, what I wanted was a Service not an Intent Service, since I wanted something that would keep running until the app closes
I am working in online application, in which there is facility of creating group. I want facility to send mail to all group user when any activity done in group. like comments , start new discussion etc. But problem is that . if any small activity i send thorusand of mail at run time. it slow the performance.
For that i am thinking to create new independent thread. to send mail which send mail to thousand of user and main thead with out any problem come to group page.
How i will make new thread in class.
thanks in advances.
for more info visit http://www.rameshsengani.in
new Thread(new Runnable() {
#Override
public void run() {
// do stuff here
}
}).start();
This is the accepted Java pre-1.5 way. You can take a look at the java.util.concurrent package and the executor framework.