users@grizzly.java.net

Re: Best Practice to broadcast / send private messages to client(s)

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Tue, 21 Oct 2008 10:21:17 -0700

Salut,

Ken--_at_newsgroupstats.hk wrote:
> Sorry about that I feel Grizzly is a little bit complicated to me.
>
> In the past, I use the following code with core jdk nio api:
>
> private HashMap<TcpClient> clientList = new HashMap();
> public void run() {
> while (bRun) {
> try {
> int keys = selector.select();
> if (keys > 0) {
> Set keys = selector.selectedKeys();
> Iterator iterator = keys.iterator();
> while (iterator.hasNext()) {
> SelectionKey objSelectionKey =
> (SelectionKey)iterator.next();
> iterator.remove();
> if (objSelectionKey.isValid() &&
> objSelectionKey.isAcceptable()) {
> ServerSocketChannel objReadyChannel =
> (ServerSocketChannel)objSelectionKey.channel();
> SocketChannel socketChannel =
> objReadyChannel.accept();
> socketChannel.configureBlocking(false);
> socketChannel.register(selector,
> SelectionKey.OP_READ);
> TcpClient client = new TcpClient(socketChannel);
> clientList.put(client.getID(), client);
> }
> // handle read
> if ()
>
> // handle write
> if ()
> }
> }
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
> }
> public void sendMessageToClient(String clientId, ByteBuffer message) throws
> IOException {
> clientList.get(clientId).getSocketChannel().write(message);
> }
> public void boardcast(ByteBuffer message) throws IOException{
> Enumeration en = clientList.enumeration();
> // boardcast
> }
>
> I start to play Grizzly now and I have no idea how to build code with
> similar purpose as Grizzly seems to encapsulate SocketChannel. I start with
> Echo Server example:
>
> public void startSIPServerDemo() throws Exception {
>
> Controller controller = new Controller();
>
> TCPSelectorHandler tcpSelector = new TCPSelectorHandler();
> InetAddress address = InetAddress.getByName("0.0.0.0");
> tcpSelector.setInet(address);
> tcpSelector.setPort(8080);
> controller.addSelectorHandler(tcpSelector);
>
> Pipeline mySharedPipeline = new DefaultPipeline();
> mySharedPipeline.setMaxThreads(5);
>
> controller.setPipeline(mySharedPipeline);
>
> ProtocolChainInstanceHandler pciHandler = new
> ProtocolChainInstanceHandler() {
>
> final private ProtocolChain protocolChain = new
> DefaultProtocolChain();
>
> @Override
> public ProtocolChain poll() {
> return protocolChain;
> }
>
> @Override
> public boolean offer(ProtocolChain instance) {
> return true;
> }
> };
> controller.setProtocolChainInstanceHandler(pciHandler);
>
> ProtocolChain protocolChain = pciHandler.poll();
> protocolChain.addFilter(new MyParserProtocolFilter());
> protocolChain.addFilter(new MyProcessorFilter());
>
> controller.start();
> }
>
> Any cure?

Hum...I think I might need more information, but from the code snipped
you dropped above, you want to get a reference to the SocketChannel in
order to handle the read/write operations. When are you invoking the
sendMessageToClient() exactly? The Grizzly code pasted above is start a
server based application, but in you NIO example you seems to want to
write a client based application. Are you planning to do a client
application or server?


Let's handle the read operation. First, you will add the ReadFilter to
the ProtocolChain:

protocolChain.addFilter(new ReadFilter());

That ProtocolFilter will handle the read operations for you. That
ProtocolFilter will be invoked when OP_READ (SelectionKey.isReadable()
== true). Next you will inject your ProtocolFilter instance:

protocolChain.addFilter(new MyProtocolFilter());

Inside your ProtocolFilter, you will get a hold of the SocketChannel by
doing:

Context.getSelectionKey().channel()

Then from there you read or write.

Now if you are planning to write a client, take a look at:

http://weblogs.java.net/blog/jfarcand/archive/2008/06/writing_a_tcpud_2.html

Mainly, you can either use a CallbackHandler for getting notified for an
OP_READ or OP_WRITE operations. You can still use ProtocolFilter as well
(as described inside the blog). Let me know if that help.

A+

-- Jeanfrancois







>
>
>