I've built a simple Java program that works as a server locally.
At the moment it does a few things, such as previews directories, forwards to index.html if directory contains it, sends Last-Modified header and responds properly to a client's If-Modifed-Since request.
What I need to do now is make my program accept persistent connections. It's threaded at the moment so that each connection has it's own thread. I want to put my entire thread code within a loop that continues until either Connection: close, or a specified timeout.
Does anybody have any ideas where to start?
Edit: This is a university project, and has to be done without the use of Frameworks.
I have a main method, which loops indefinitely, each time it loops it creates a Socket object, a HTTPThread object is then created (A class of my own creation) - that processes the single request.
I want to allow multiple requests to work within a single connection making use of the Connection: keep-alive request header. I expect to use a loop in my HTTPThread class, I'm just not sure how to pass multiple requests.
Thanks in advance :)
I assume that you are implementing the HTTP protocol code yourself starting with the Socket APIs. And that you are implementing the persistent connections part of the HTTP spec.
You can put the code in the loop as you propose, and use Socket.setSoTimeout to set the timeout on blocking operations, and hence your HTTP timeouts. You don't need to do anything to reuse the streams for your connection ... apart from not closing them.
I would point out that there are much easier ways to implement a web server. There are many existing Java web server frameworks and application servers, or you could repurpose the Apache HTTP protocol stacks.
If it should act like a web service: Open 2 sockets from the client side, one for requests, one for
responses. Keep the sockets and streams open.
You need to define a separator to notify the other side that a
transfer is over. A special bit string for a binary, a special
character (usually newline) for a text-based protocol (like XML).
If you really try to implement an own http-server, you should rather make use of a library that already implements the HTTP 1.1 connection-keepalive standard.
Some ideas to get you started:
This wikipedia article describes HTTP 1.1 persistent connections:
http://en.wikipedia.org/wiki/HTTP_persistent_connection
You want to not close the socket, but after some inactive time period (apache 2.2 uses 5 seconds) you want to close it.
You have two ways to implement:
in your thread do not close the socket and do not exit the thread, but instead put a read timeout on the socket (whatever you want to support). When you call read it will block and if the timeout expires then you close the socket, else you read next request. The downside of this is that each persistent connection holds both a thread and a socket for whatever your max wait period is. Meaning that your solution doesn't scale because you're holding threads for too long (but may be fine for the purposes of a school project)!
You can get around the limitation of (1) by maintaining a list of tuples {socket,timestamp}, having a background thread monitor and close connections that timeout, and using NIO to detect a new read on an existing open socket. So after you finish reading the initial request you just exit the thread (returning it to the thread pool). Obviously this is much more complicated but it has the benefit of freeing up request threads.
Related
I am learning socket and server/client model concept and having a hard time understanding the server client concept. If a client sends a request, can server sends more than one respond? Or we have to put everything in one respond?
For a memory game program, when a client click a card, the action will send a request to server in order to turn the card in every player's program, if the second card does not match, the server tells players wait 2 secs, turn the 2 cards back, and then assign turn to next player. Can a server does this in multiple responds or it has to do it in single respond? Since no client requests for some responds, so I don't know if it is achievable or not.
If you're talking about TCP connections, after the connection has established client and server are equivalent, both are free to send data as long and as much they like and/or shut down their end of the connection.
Edit: After several passes I think i have understood what the second paragraph of your question is aiming for.
There is, of course, nothing which would stop the server from doing anything.. What your server seems to do, most of the time, is blocking on a InputStream.read() operation. If you want the server to operate even when no network input happens, one solution might be to use a read timeout, or check the input stream for readability before actually reading.
This is not your complete answer.
For one request, you get one response back.
Please read on this information in wikipedia for the basics
"Request-response, also known as request-reply, is a message exchange pattern in which a requestor sends a request message to a replier system which receives and processes the request, ultimately returning a message in response. This is a simple, but powerful messaging pattern which allows two applications to have a two-way conversation with one another over a channel. This pattern is especially common in client-server architectures.1
For simplicity, this pattern is typically implemented in a purely synchronous fashion, as in web service calls over HTTP, which holds a connection open and waits until the response is delivered or the timeout period expires. However, request-response may also be implemented asynchronously, with a response being returned at some unknown later time. This is often referred to as "sync over async", or "sync/async", and is common in enterprise application integration (EAI) implementations where slow aggregations, time-intensive functions, or human workflow must be performed before a response can be constructed and delivered."
I've been thinking about this all day, i dont really think if the Title is the correct one but here it goes, let me explain my situation: Im working on a project, a server made in Java for clients made in Delphi. Conections are good, multiple clients with its own threads, i/o working good. The clients send Strings to the server which i read with BufferedReader. Depending on the reserved words the server receives, it makes an action. Before the client sends the string, it inserts information to a SQL Server database so the server can go and check it after getting the order/command via socket. The server obtains the information in the database, process it, and send it to... let's call it "The Dark Side".
At the moment that the transaction is done, and the info is sent to the dark side, the server inserts the information... cough cough, dark information into a database table so the client can go and take what it requested. BUT, i need to report that to the client! ("Yo, check again the database bro, what you want is there :3").
The conection, the socket is made in other class. Not the one that i want to use to answer to the client, so if i dont have the socket, i dont have the OutputStream, which i need to talk back. That class, the one processing and sending information to the dark side, is going to be working with hundred of transactions in group.
My Issue is here: I can't report to the client that is done because i dont have the sockets references in that class. I instance the clients thread like:
new Client(socket).start();
Objects without references variables, but, i have an option i can take: Store the Sockets and their ip's in a HashMap object at the moment that a new connection is made, like this:
sockets.put(newSocket.getInetAddress().getHostAddress(), newSocket);
Then i can get the socket(so i can get the OutputStream and answer) calling an static method like this:
public static Socket getSocket(String IP) {
Socket RequestedSocket;
RequestedSocket = sockets.get(IP);
return RequestedSocket;
}
But i want you to tell me if there is a better way of doing this, better than storing all of those sockets in a list/hashmap. How can i get those objects without reference variables ? Or maybe thats a good way of doing it and im just trying to overpass the limits.
P.S.: I tried to store the Client objects in the database, serializing them, but the sockets can't be serialized.
Thanks.
This is a design issue for you. You will need to keep track of them somewhere, one solution might be to simply create a singleton class [SocketMapManager] for instance that holds the hashmap, so that you can access it statically from other classes. http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html
Any solution that tells you to keep a reference to the socket/ connection/ stream is bad -> as that means your connections are going to be held up while the server does its work.
You have a couple of options open
1. have the clients act as servers too. when they connect, they give the server their IP, port and some secret string as part of the hand shake. This means you have control over client code to make this happen.
the servers have a protocol to either take new jobs or check status of old jobs. Client pools the server periodically.
clients connect to database or other application (web service or plain socket like the original app) that connects to data base to get the status of the job. Meaning server gives client a job id.
a socket is open then it one OS resource open. can read up Network Programming: to maintain sockets or not?
All depends on
1. how many client connect at a time/ in 5 minutes.
2. how many seconds/ minutes does one client's request take to process
if number of clients in 5 minutes is maximum (in next 3 years) 300 at a time/ in any 5 minute duration and each request takes at a max 50 seconds to process then a dedicated server with max 50,000 sockets should suffice. Else you need async or more servers (and a DNS/ web server/ port forwarding or other method for load balance)
I'm having a bit of a problem trying to understand what is the flow of the operations, and what exactly you have at disposition. Is this sequence correct?
1. client writes to database (delphi)
2. client writes to server (delphi)
3. server writes to database (java)
4. server writes to client (java)
5. client reads database (delphi)
And the problem is pass 4?
More important: you are saying that there isn't a socket in the Client class, and that you don't have a list of Client too?
Are you able to use the reflection to search/obtain a socket reference from Client?
If you say you don't have the socket, how could it be that you can add that socket in a HashMap?
Last but not least: why do you need to store the socket? Maybe every client opens one connection which is used for multiple requests?
It could be beautiful if all the answers could be conveyed to just one ip:port...
I have a standard client/server setup.
The program I'd like to build acts a lot like a mail office(which is my Server). Multiple people (client with ObjectOutputStream) hand the office (server with the single ObjectInputStream) mail with an attached address and the office sends the mail where it is supposed to go. If possible, I'd like to have one ObjectInputStream in the server that blocks, waiting for "mail" to come in from any ObjectOutputStream, then sends the "mail" where it's supposed to go. This way I can just have one thread that is completely dedicated to receiving data and sending it.
I will have a thread for each person's client with their ObjectOutputStream, but would like to not also need a matching thread in the server to communicate with each person. I am interested in this idea because I find it excessive to build tons of threads to separately handle connections, when it's possible that a single thread will only send data once in my case.
Is this feasible? or just silly?
Use a JMS queue of Java Message Service, is the design pattern for this case.
http://en.wikipedia.org/wiki/Java_Message_Service
If you have in the server app just one instance of ObjectInputStream and you have many clients then this instance needs to be shared by all threads thus you need to synchronize the access to it.
You can read more here. Hope this helps.
OR
You can have a pool of ObjectInputStream instances and using a assignment algorithm like Round Robin (doc) you can return the same instance for each x order thread for example ... this will make the flow in the server app to be more paralleled
Your question doesn't make sense. You need a separate pair of ObjectInputStream and ObjectOutputStream per Socket. You also need a Thread per Socket, unless you are prepared to put up with the manifest limitations of polling via InputStream.available(), which won't prevent your reads from blocking. If you are using Object Serialization you are already committed to blocking I/O and therefore to a thread per Socket.
Is it quite easy to handle multiple requests on a Java TCP / IP socket. Simply accept a message and spawn a thread. Accept another message and spawn another thread. The thing is once you start spawning threads things get more non deterministic. Say you have 10 clients and one client keeps firing requests and the other 9 nine who send requests at 10% percent of the hyperactive client, find it harder to get a look in.
One way you could handle this is have a hashmap of semaphores in your server where every client has a corresponding semaphore. Before you handle a request for any client, you could make it go thru its semaphore and configure the semaphores so that each client could only have a certain number of requests at any one time.
At this stage,I'm thinking yeah that works but is there a better way or a library that does this?
... but is there a better way ...?
I use one accepting-thread per serversocket and a pool of pre-spawned threads to handle the workload. The accepting-thread only accepts connections (does nothing else) and gives the handler-socket to one of the threads in the pool. That thread then works with the handler-socket until the client is done, then closes the handler-socket.
You can scale-out this setup as far as you like: If you notice that the accepting-thread is waiting for pool-threads most of the time then you need to x2 your number of pool-threads, if you notice that the accepting-thread is the bottle-neck you create both (A) another accepting-thread and (B) another socket from which it accepts connections and optionally (C) put these on another machine.
The specific problem you are describing with the one hyper-active client can be intended/desired if the client is more important than others: in which case you have to do nothing. Or it can be considered a denial-of-service attack, in which case you should have a heuristic that just disconnects the client and temporarily bans its ip-address.
I am writing the code for a server that would help two different applications in different platforms communicate with each other. To visualize it a bit it would be something like this :
App1<------>Server<------>App2
What server does is rear var1 from app2, write it to app1, then read var2 from app1 and write it to app2. Like this :
while(true){
var1 = app2stream.readInt();
app1stream.writeInt(var1);
var2 = app1stream.readDouble();
app2stream.writeDouble(var2);
}
My problem is that at some point i have this code at my server :
app1.accept();
app2.accept();
What this means is that no matter what, and given the fact that the server is always running, app1 is the one that should connect first since app1.accept() is a blocking method.
Is there any way around this? It would be great to allow the two applications to connect to the server regardless of who "came" first and then wait for the server to proceed with the above code. Can i use threads just for the accept() part and then pass the streams to the other thread? I read a bit about channels but got a bit buffled, any examples would be great.
Use NIO
It allows you to do non-blocking sockets (including accept) using the Selector class.
Basically, it gives you much more native access to the system libraries and the ability to handle your task without having to multi-thread.
Only have one accept call, and one server socket. You can make the determination which app has connected once they connect. If you can't get it from the connection details, have them send an authcode (probably a good idea anyway) which you can map to your app.
You should probably treat them both the same unless they say otherwise.
For example when the each socket connects send a "what client?" message.
Then check whether the client responds with 1 or 2.
If both respond with 1 or something just disconnect both.
I think the "standard" way to do this is to have the server listening on a port, and when a message comes in, immediately spin off a new thread to handle it, then go back to listening for another message. Then, as Glowcoder says, make all the connections in the same loop and make it figure out which is which after connecting.
I suppose the alternative is to have multiple threads, each listening on different ports. I've never tried to do that, I'm not sure if one would block until a connection was made and so you'd never get to the other thread.