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 12:00:19 -0700

Salut,

Ken--_at_newsgroupstats.hk wrote:
> Sorry to confuse you. The code I post above is my quick ugly draft.
>
> I want to build a server application. For example stock quote server.

hey hey look here then:

http://www2.sebastiendionne.ca:8282/grizzly/grizzly-migration-guide-part-1.html

In this tutorial, Sebastien explain how to build a stovk quote
application. Let use know if that help.

A+

-- Jeanfrancois

>
> Users login to my server by a login id and password and all logined users
> will have a session (the HashMap) in server.
>
> Stock price data realtime push to clients (boardcast).
>
> Whenever Dowjones index move, the server push dowjone index to all logined
> users by a broadcast() method.
>
> Some user have interest to specific stock (e.g. IBM) so whenever IBM price
> move, the server push IBM price to the user by a sendMessageToClient()
> method.
>
> So I want to have a broadcast() function [send messages to all logined
> users]
> and sendMessageToClient() [send messages to specific logined user] method
> for convenience.
>
> MyServer.getInstance().broadcast(Message msg);
> MyServer.getInstance().sendMessageToClient(String userId, Message msg);
>
> That's my old pattern for building a tcp server.
>
>
>
>
> Jeanfrancois Arcand-2 wrote:
>> 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
>>
>>
>>
>>
>>
>>
>>
>>>
>>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>
>>
>>
>