The call on ServerBootstrap.bind() returns a Channel but this is not in a Connected status and thus cannot be used for writing to client.
All the examples in Netty documentation show writing to a Channel from its ChannelHandler's events like channelConnected - I want to be able to get a connected Channel not in the event but as a reference outside the event , lets say some client code using my server component. One way is to manually code for waiting for channelConnected event and then copying the Channel reference.But this may be reinventing the wheel.
So the question is : Is there a blocking call available in Netty that returns a Connected Channel ?
edit : I am using Oio Channels , not Nio.
You could create a blocking call, but I think you maligned the event based approach too quickly. This is a contrived example, just to make sure I understand what you're trying to do:
Netty Server starts
A DataPusher service starts.
When a client connects, the DataPusher grabs a reference to the client channel and writes some data to it.
The client receives the pushed data shortly after connecting.
More or less correct ?
To do this, your DataPusher (or better yet, one of its minions) can be registered as a ChannelHandler in the server pipeline you create. Make it extend org.jboss.netty.channel.SimpleChannelHandler. The handler might look like this:
DataPusher dataPusher = getMyDataPusherReference();
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
dataPusher.doYourThing(e.getChannel()); // do something in another thread....
}
If you are determined to make it a blocking call from the DataPusher's perspective, just have it wait on a latch and have the minion drop the latch.
Not sure if that's what your'e looking for.....
After all the exchanges above, I still don't see that any of this is necessary.
Surely all you have to do is just accept the connection from the external service; don't register it for any events; then, when the other client connects, register for I/O events on both channels.
The external service doesn't know or care whether you are blocked in a thread waiting for another connection, or just not responding for some other reason.
If he's writing to you, his writes will succeed anyway, up to the size of your socket receive buffer, whether you are blocking or not, as long as you aren't actually reading from him. When that buffer fills up, he will block until you read some of it.
If he is reading from you, he will block until you send something, and again what you are doing in the meantime is invisible to him.
So I think you just need to simplify your thinking, and align it more with the wonderful world of non-blocking I/O.
Related
I read from a stream created by Socket.getInputStream(). When I use it, it blocks until it gets new data(exactly what it should). Now I need the stream to read something (see below). But when I start a new read it will give me unspecified output(or not?). My question is:
How can I interrupt the actual read, so I can use the read method?
Details: I connect to a server and send commands to it. From time to time the server sends messages to my client (event notifications), which I need to register. I want to be able to send commands while I'm waiting for this messages. When I send a command the answer to this command is read from the stream. And here is the problem: I'm still listening to the messages while I try to read my answer. So I need something that interrupts the current read.
The problem with stopping the event processor from reading is that you introduce a race condition: What happens if the server sends an event right after you terminated the read? The "response" that you read would wind up being an event.
The proper way to do this is to do all your reading, both events and responses, in one place and handle the responses like an event also. Right before you send a command, register a listener for the response, then send the command. When the reading thread sees a response, have it find the proper listener and notify it that the response has been received.
Easiest, best way to handle this IMO is to use an asynchronous listener with event callbacks. DataFetcher is an implementation (Also see Timeout and PartialReadException, dependencies in the same project/package, and IOUtils, which has capabilities to directly connect a FetcherListener with an InputStream)
I am using netty for developing my server.
I am looking for setting the setInterestOps for a channel.
In netty 3 there is a method call setInterestOps in Channel class.
But in netty 4 I can't find it.
Can anybody tell me where it is?
Thank you
Channel.setInterestOps() in Netty 3 was used to suspend or resume the read operation of a Netty Channel. Its name and mechanic were unnecessarily low-level, so we changed how we deal with the suspension and resumption of the inbound traffic.
First, we added a new outbound operation called read(). When read() is invoked, Netty will read inbound traffic once, and it will trigger at least one channelRead() event and a single channelReadComplete() event. Usually, you continue to read by calling ctx.read() in channelReadComplete().
However, because having to call ctx.read() for every channelReadComplete() is not very interesting, Netty has an option called autoRead, which is turned on by default. When autoRead is on, Netty will automatically trigger a read() operation on every channelReadComplete().
Therefore, If you want to suspend the inbound traffic, all you need to do is to turn the autoRead option off. To resume, turn it back on.
Use Channel.config().setAutoRead(true/false);
I have some problems understanding how a socket should be handled. I get that server socket must runs in its own thread, because it must check if there are new connections. Now, i'm not sure if every socket opened by a new connection should runs in a thread.
What i have in mind is checking every x time the socket states. If it has something to be read, then read. If not, check the next socket. I see some examples where this process is done in a thread, but i dont want a socket to do stuff, just want to read if it has some data, and process them.
The answer is no, you don't need to listen in a separate thread. But, just realize that while you are "listening" your entire program will be waiting for that to complete before moving onward.
So unless you are fine with your entire program waiting, I would suggest a separate thread.
You can also have one thread which communicates with all sockets in a round-robin manner. It checks each socket if it has new data, and when it hasn't it checks the next.
Another alternative is to use NIO (New Input/Output).
The idea behind NIO is that you have a thread with one Selector which owns multiple Channels (a channel can be a network socket or any other IO interface). You then call selector.select() in a loop. This method blocks until one or more channels have data, and then returns a set of these channels. You can then process the data the channels delivered.
Here is a tutorial.
The problems with round-robin using available() are many.
It assumes that available() actually works, which isn't guaranteed.
It assumes that all clients need the same amount of service.
N-1 clients wait while one client is serviced.
A non-responsive client can block not only your application but all the other clients.
I'm sure there are more.
Don't do this. Use threads or NIO.
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.
I'm writing a UDP client-server pair for a networks class, and I have hit on a problem. This is a rather unorthodox networks assignment, so a little background first:
The goal is to create a server to implement push-based notifications. The key point here is that the server has to contact the client at whatever address it was last seen, as well listen for the client's control packets. So therefore, I have a thread running on the client periodically sending out UDP packets to the server, which logs their origin for when it needs to send out a response. This technique also busts through NAT's, as the send refreshes the address translation.
So then, here is my dilemma: Unless I'm mistaken, the NAT maps its own address and a generated port number onto it's clients address port combination. Therefore, in order to successfully traverse the NAT, I need to move all my packets through one port on the client machine. The updater thread would simply have to listen for a time, push out an update packet, and go back to listening.
Then here is where it get hairy. If the original thread, which wants to perform some action, wants the port, it has to wake the announcer, which is blocking while waiting for the response.
How can I pull this off in Java?
P.S.: If it turns out that the NAT would allow a communication on a different port to go through, then things are awesome.
Note: I am not necessarily telling you this is the right way to solve your larger problem.
But the answer to your top-line question, "How do I signal a sleeping thread in Java" is: Call interrupt() on the thread. You'll need a more elaborate mechanism in place to communicate why it has been interrupted, but that's a start. interrupt() will wake a sleep()ing or wait()ing thread with an InterruptedException, but I don't think that's really what you're asking.
This will not wake up a thread blocked on a read() call, say a socket. It sounds like you are using a DatagramSocket, in which case you have a couple of options:
Use a non-blocking implementation. (aka, "Selector-based", or New I/O (nio) in Java lingo) See e.g. DatagramChannel; also maybe this SO question and/or this one
Use normal Java I/O, set a socket timeout of suitable length, and wrap your calls to read() in a loop, checking for the appropriate condition.
Look at the following links :
Thread signaling
What is a condition variable in java
Java signal handling
How is the thread 'sleeping'?
Typically, inter-thread cooperation revolves around
wait() and notify() calls.
Selectors are one approach I would consider. Haven't used Java's version yet, so take this with a grain of salt.
You could have one selector watching both the UDP channel and an in-process channel, waking up on activity of either.
There's an introduction to selectors halfway down http://java.sun.com/developer/technicalArticles/releases/nio/ . See also the API docs of AbstractSelector and its interface.