Obtaining specific SocketChannel for OP_WRITE modification and write operation - java

I am implementing a simple chat server using Java NIO for performance reasons and I have read from several sources where they advised against registering a SocketChannel with a Selector to listen to both read and write events at the same time, but only register for write event when there is data available to be written.
Now what I don't know is how to obtain a specific SocketChannel object for OP_WRITE modification and write operation.
Here is the scenario, 20 chat clients establishes a connection with the chat server at a given time. ChatClient 1 sends a message that is meant to be delivered to ChatClient 15. After reading the data from ChatClient 1's SocketChannel, how do I obtain ChatClient 15's SocketChannel specifically which I intend to modify to OP_WRITE and then write the data meant for it.
I don't know if this approach will work, but I was thinking of adding the SocketChannel object returned when ServerSocketChannel.accept() method is called to a list with an index that can be used to look it up later. So when there is data available to be written to Client 15, I look up the SocketChannel object from the list and then perform the OP_WRITE modification and then write the data. Will this work?
Thanks for your time.

It's just a data structure problem. You know which client you want to write to, so you just need a data structure you can get his SocketChannel from. You can key it any way you like: a sequential index, a client identifying string, his IP address; whatever works for your application.

Related

Java: Multiple sockets send and receive maintain in a single thread

I am a new java socket developer. In my solution has three sockets for sending and receiving. I want to receive three socket's data in a single thread. For this reason, how i get notification which socket get data from remote.
Handling multiple streams (those of the sockets) within a single thread is possible. It requires the use of socket channels (from java.nio.channels) and of a (single) Selector.
You create a Selector and register the SocketChannels.
To learn about any new possibility for an i/o operation, you call the Selector's select() method, which returns whenever one of the channels is ready for reading, writing or accepting. You'll have to learn the ready channel (i.e., obtain its "key"), and call its appropriate data transfer method.
There is some sample code to be found on the net.
PS: It might be easier to use threads.

How to get a socket object without a reference variable?

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...

Is it possible to use multiple java ObjetOutputStream objects to write to a single java ObjectInputStream object?

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.

Listener for incoming messages

I am currently trying to create a chat application using the Socket and ServerSocket classes, but i kinda ran into a roadblock. I need some kind of listener to execute a certain block of code when a message is incoming from the server or the client, but i can't seem to find one. An option would of course be to just check for incoming messages every 10 ms or something, but isn't there a smarter solution?
In general, you should assign a Thread to each Socket you are reading, so that Thread can block on the socket and wait for incoming information.
You should take a look at DataFetcher: http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/
This class can work asynchronously, and notify a FetcherListener when new data is available
I recommend Netty or Mina. As for Socket and ServerSocket, the read() calls are blocked, so in a way the code below the read()s are executed whenever there's incoming data.
Beware of the incomplete message though, because Sockets provide a stream of bytes and the applications are usually more comfortable with discrete messages.

How to design a multi-client/server application?

In a socket-based application (client/server), I want to make the server perform as a proxy(manager) to handle several clients, and to get the message from one client and send it to the client, identified by an ID.
How can I know the required client running on different thread, how can I get the socket of the associate client that the id represents?
Just keep an in-memory hashmap of some sort of client-id to the java.net.Socket object that represents that client's socket. You need to come up with some way of assigning client IDs, either client supplied, or server-supplied through some authorization scheme.
When a message comes in for a client ID, grab the socket from the map and send it a message. This map needs to be stored in a singleton-type object, and needs to be properly synchronized. Use a concurrent hash map. Also, socket reads and writes would need to be synchronized if you're going multi-threaded.
I have posted some example code as a github gist. It's a bit different than I explained above. I don't store sockets in the map, I store client handlers which have the socket. Also, socket reads don't need synchronization: each clients has its own thread which is the only thread reading from the socket. Socket writes do need to be synchronized though, because the thread of the sending client is writing to the socket of the receiving client.
You're probably better off using something like JBoss Netty rather than rolling your own though.
you can keep a lot of information about ID so each time it connects you get like the ip and save the thread it is running on and then you use like a hashmap to link the id to all that info then you can easily get the thread it is running on and send the information to the correct client
Save the messages to be delivered into a database, and make your threads check the database for new messages to be delivered to "their" clients on a regular basis.
If you do not want a dedicated database for the messages, build a flat file with simple ClientID->Socket mappings and use it like a "telephone book" kind of lookup system. Depending on the amount of clients you are planning to add, each thread could pre- and regularily reload such a file into it's memory for faster access...

Categories