Page 1 of 2 12 LastLast
Results 1 to 10 of 19
  1. #1
    Power Member
    Join Date
    Nov 2012
    Posts
    182

    How to send data to single client rather than all?

    Whilst evaluating Lightstreamer I have created a little "echo" facility using a metadata adapter and a data adapter. It basically works, so I feel I have the fundamentals within my grasp. My problem is that when I have multiple clients use the echo facility, the message sent by one client is echoed back to all the connected clients rather than only the one that sent it. A rather novel facility should I want to use instant messaging - but in this case I do not. I just want the message sent back to the client that sent it - and that is all.

    Clearly I something fundamentally wrong here - probably to do with my "subscribe" and "sendMessage" methods. Can somebody give me a pointer as to what I should be doing below:

    Code:
    public void subscribe(String itemName, Object itemHandle, boolean needsIterator) throws SubscriptionException, FailureException  {
            // We must be ready to accept subscription requests. If we receive an "echo" item we will start a thread to
            // handle the data.
            // If more users subscribe to the “echo” item, the subscribe method is not called anymore. 
            // When the last user unsubscribes from this item, our Adapter is notified through the unsubscribe call
            logDebug("EchoDataAdapter subscribed: "+itemHandle.toString());    
            if (!itemName.equals("echo")) {
                // only one item for a unique echo is managed
                throw new SubscriptionException("No such item");
            }
            
            assert(subscribed == null);
    
            subscribed = itemHandle;
        
        }
        
        public void sendMessage(String message) {
            // Receives a message from the metadata adapter, which we will simply echo back
            //logDebug("EchoDataAdapter received sendMessage: "+message);
            this.echoMessage(message);
        }
    
        private void echoMessage(String message) {
            final Object currHandle = subscribed;
            final HashMap<String, String> echo = new HashMap<String, String>();
            echo.put("message", message);
            
            //If we have a listener create a new Runnable to be used as a task to pass the
            //new update to the listener
            Runnable echoMessage = new Runnable() {
                public void run() {
                    // call the update on the listener;
                    // in case the listener has just been detached,
                    // the listener should detect the case
                    logDebug("Echoing "+echo.get("message"));
                    listener.smartUpdate(currHandle, echo, false);
                }
            };
    
            //We add the task on the executor to pass to the listener the actual status
            executor.execute(echoMessage);
    
        }
    Also, when a connection is made a session gets created. How do I get that session identifier on the client?

    Thanks

  2. #2
    Administrator
    Join Date
    Feb 2012
    Location
    Milano
    Posts
    716
    Hi kpturner,

    Please refer to this thread for cases similar to your.

    About the session identifier, please note that The JavaScript Client API dosn't allow you to get the private identifier of a session, but if you go more deep on your needs maybe we can help you find alternative solutions.

  3. #3
    Power Member
    Join Date
    Nov 2012
    Posts
    182
    Hi - thanks for the answer.

    I haven't read the thread yet because I solved my problem by getting my client to pass a GUID as part of my subscription, and storing the unique subscription handle in a concurrentHashMap keyed by the GUID. Then when I send my message it includes the GUID, and allows me to retrieve the relevant subscription handle and echo back to the client that provided the GUID. I will see if the thread follows a similar line.

    The reason I wanted to get the session on the client side followed on from this. It struck me that if Lightstreamer is creating a unique session id for me when I connect, I should be able to use that instead of the GUID I am now generating, to keep my requests and responses unique to one client.

  4. #4
    Power Member
    Join Date
    Jul 2006
    Location
    Cesano Maderno, Italy
    Posts
    784
    If you check the Messenger demo you'll see that in the getItems code it transform the received item name, that is the same per any client, into a personalized item name so that each user gets its own personal item (we use the user to personalize the item but you can use the session if you prefer that). This also makes sure a user can't subscribe to another user item (as long as the getItems is properly implemented)

    Then in the notifyUserMessage implementation it uses the user (or again, in your case the sessionId if needed) to discern which client has sent the message.

    So there is no need to generate an id on the client to be sent to the server.

    Let me know if that's not clear.


  5. #5
    Power Member
    Join Date
    Nov 2012
    Posts
    182
    Many thanks for your support.

    I cannot see any transformation of the item name in getItems in that example. I see it cycles through the items and calls checkIMName for each one, but that doesn't do much to the items that get returned by getItems. Why is the item array called "broken" by the way?

    That said, I understand the technique you have described and have implemented it successfully. So no more GUID required

    Thanks

  6. #6
    Power Member
    Join Date
    Jul 2006
    Location
    Cesano Maderno, Italy
    Posts
    784
    Ops,

    you're right, I had a false memory, that getItems does not personalize the item name cause we decided to not user user names for our demos, my bad

    About the "broken" name, is called that way cause that metadata adapter inherits from the LiteralBasedProvider whose impleemtnation of getItems is to split the received string on the space character (hence the "broken" name as "broken in pieces").
    Using such metadata adapter permts to use an "Item List" on the client.

    see
    http://www.lightstreamer.com/docs/client_javascript_uni_api/Subscription.html for some details:

    an Item List is an array of Strings each one representing an item. For the Item List to be correctly interpreted a LiteralBasedProvider or a MetadataProvider with a compatible implementation of getItems has to be configured in the associated Adapter Set.

  7. #7
    Power Member
    Join Date
    Nov 2012
    Posts
    182
    Quote Originally Posted by Mone View Post
    ......my bad
    OMG!! An Italian using an Americanism. The world is falling apart

  8. #8
    Administrator
    Join Date
    Jul 2006
    Location
    Milan, Italy
    Posts
    521
    Quote Originally Posted by kpturner View Post
    OMG!! An Italian using an Americanism. The world is falling apart
    Heheh

  9. #9
    Power Member
    Join Date
    Jul 2006
    Location
    Cesano Maderno, Italy
    Posts
    784
    blame american series for that

  10. #10
    Power Member
    Join Date
    Nov 2012
    Posts
    182
    So back to the subject at hand, this very simple echo server is now working fine. What I need to address now is performance. What I have found with other evaluations is that I can send a very quick burst of separate messages to the server and the echos come back almost instantly. With my Lightstreamer echo server, if I send a very quick burst of separate messages to the server, the echoed responses plod back very slowly. I am using the logger on my echo data adapter to trace a message every time it is echod back, and I can see that the server is responding extremely fast. If I send a burst of 100 messages, my data adapter has processed all the "listener.smartUpdate" calls almost instantly - but the data is plodding back to my browser very slowly.

    In other words:
    * Burst of 100 outbound messages
    * Data adapter has echoed them all back virtually instantly
    * 100 messages arrive sequently on my browser very slowly, like only one or two per second

    Something is slowing matters down, and it doesn't seem to be the data adapter itself. What should I be looking at to try to work out what is going wrong? Possibly the configuration of subscription? Any pointers?

 

 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
All times are GMT +1. The time now is 11:46 AM.