I\'m mostly there with Netty but one concept is still alluding me, and I can\'t find anything in the tutorials and so on. Firstly I do understand that Netty is asynchronous,
You have to handle it in the Handler with messageReceived(). I'm not sure what your issue is exactly. My guess is you have a response to a request that changes depending on what request was made? Maybe a concrete description of something you are doing of a response that has to know what request it came from. One thing you might be able to do is to pass a long living object the handler that knows the outstanding request, and it can match up the response when it receives it. The pipeline factory method can pass a reference to a manager type object to the Handler.
This was pretty much what I was trying to say. Your Handler is created in the PipelineFactory which is easy to pass parameters to the Handler from there:
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.nulDelimiter()));
pipeline.addLast("decoder", new XMLDecoder() );
pipeline.addLast("encoder", new XMLEncoder() );
// notice here I'm passing two objects to the Handler so it can
// call the UI.
pipeline.addLast("handler", new MyHandler(param1, param2));
return pipeline;
}
});
When you create your pipeline you'll add your Handler upon a new connection. Simply pass one or more objects that allows it to communicate back to the UI or a controller.
Jestan is correct. In my case I have a client that need to process price tick data. I use Antlr for the parsing. I fire my events in my parser, but in my case my protocol is String based. Below is an example without Antlr, I pass the String message in your case it could be the users.
//----------------- Event --------------
public class DataChangeEvent {
private String message;
public DataChangeEvent(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
//----------------- Listener --------------
public interface DataChangeListenter {
public void dataChangeEvent(DataChangeEvent event);
}
//----------------- Event Handler that fires the dataChange events --------------
// This class needs to be static since you need to register all your classes that want to be notified of data change events
public class DataChangedHandler {
private static List<DataChangeListenter> listeners = new ArrayList<DataChangeListenter>();
public static void registerDataChangeListener(DataChangeListenter listener) {
listeners.add(listener);
}
public static void fireDataChange(DataChangeEvent dataChangeEvent) {
for(DataChangeListenter listenter : listeners) {
listenter.dataChangeEvent(dataChangeEvent);
}
}
}
//----------------- Example class that implements the listener and registers itself for events --------------
public class ProcessMessage implements DataChangeListenter {
public ProcessMessage() {
DataChangedHandler.registerDataChangeListener(this);
}
public void dataChangeEvent(DataChangeEvent event) {
//Depending on your protocal, I use Antlr to parse my message
System.out.println(event.getMessage());
}
}
//---------------- Netty Handler -----------
public class TelnetClientHandler extends SimpleChannelHandler {
private static final Logger logger = Logger.getLogger(TelnetClientHandler.class.getName());
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
String message = (String) e.getMessage();
DataChangedHandler.fireDataChange(message);
}
}