Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Messaging module problems

    I have some problems with the messaging module that I didn't have with previous versions. Just enter a channel name and press "Go". Nothing happens. Change it and press "Go". Nothing happens.
    This was not happening with previous versions, since a lot of time passed since I implemented the messaging functionality in my site and it was working.
    Using 6.0-p20160813 power. But this also happens with 27.09. Chrome 52.0.2743.116 (64-bit)
    Code:
    public class TestingModule implements EntryPoint {
    
        @Override
        public void onModuleLoad() {
    
            final VLayout vlayout = new VLayout();
            DynamicForm df = new DynamicForm();
            final TextItem ti = new TextItem("cn", "channel name");
            df.setFields(ti);
            IButton button = new IButton("go!");
            button.addClickHandler(new ClickHandler() {
    
                @Override
                public void onClick(ClickEvent event) {
                    Messaging.subscribe((String)ti.getValue(), new MessagingCallback() {
                        @Override
                        public void execute(Object data) {
                            SC.logWarn("Received: " + (String) data);
                        }
                    });
                    Record rec = new Record();
                    rec.setAttribute("channel", ti.getValue());
                    DataSource.get("testingDS").performCustomOperation("testMethod", rec, null);
                }
            });
            vlayout.addMembers(df, button);
            vlayout.draw();
    
        }
    
    }
    Code:
    public class TestingDMI {
    
        private static final Logger LOG = Utils.getLogger(TestingDMI.class);
    
        public DSResponse testMethod(DSRequest dsRequest) throws Exception {
    
            LOG.info("TestingDMI: ExecuteMethod()");
            String channel = (String) dsRequest.getValues().get("channel");
            LOG.info("Channel: " + channel);
    
            ISCMessageDispatcher dispatcher = ISCMessageDispatcher.instance();
    
            for (int i = 0; i <= 500; i++) {
                dispatcher.send(new ISCMessage(channel, "message " + i));
            }
    
            return new DSResponse();
        }
    }
    Code:
    <DataSource ID="testingDS" serverType="generic">
    
        <operationBindings>
            <operationBinding operationType="custom" operationId="testMethod">
                <serverObject className="de.mks_infofabrik.kids.server.test.TestingDMI"
                    methodName="testMethod" />
            </operationBinding>
        </operationBindings>
    
    </DataSource>

    #2
    If I leave the same channel name, it works (but also not always).
    So the messaging module is configured correctly.

    Comment


      #3
      And in the server logs I see that all messages are sent correctly to the correct channel. But the client doesn't get them!

      Maybe some timing issue? But as I said, this was not happening before.

      Comment


        #4
        The way your code is structured, you're not guaranteed to receive that message. Subscribing is an asynchronous operation, and it may complete after the custom operation has already attempted to send data to the channel. If you place the code for performCustomOperation() inside the MessagingCallback, you should see reliable delivery.

        As to why you see a different between versions, any library change, setting change or infrastructure change anywhere in the system could change the timing here.

        Comment


          #5
          Originally posted by Isomorphic View Post
          If you place the code for performCustomOperation() inside the MessagingCallback, you should see reliable delivery.

          As to why you see a different between versions, any library change, setting change or infrastructure change anywhere in the system could change the timing here.
          but the performCustomOperation() is the triggering method to call the server-method which sends the messages. If I call it inside the execute() method, it will never be called, since the execute() method is being called when receiving a message, or am I understanding something wrong?

          and it will be called for every message received, which is not what I want. I only need to call it once.

          Comment


            #6
            What is the difference of my code and your code in http://www.smartclient.com/smartgwte...ng_stock_chart ?
            Code:
            [LIST][*]Messaging.subscribe("stockQuotes" + startParameter, new MessagingCallback() {[*]@Override[*]public void execute(Object data) {[*]updateStockChart(data);[*]}[*]});[*]StockQuotesDS.getInstance().fetchData(null, new DSCallback() {[*]public void execute(DSResponse response, Object data, DSRequest request) {[*]initialData = new RecordList(response.getData());[*]lastValues = new RecordList(initialData.duplicate());[*]chartData = new RecordList(initialData.duplicate());[*]String currentDate = dateFormatter.format(new Date());[*]for (int i=0; i<chartData.getLength(); i++) {[*]Record r = chartData.get(i);[*]r.setAttribute("lastUpdated", currentDate);[*]}[*]}[*]});[/LIST]
            You also subscribe and immediately you call a fetch.
            Last edited by edulid; 30 Sep 2016, 01:23.

            Comment


              #7
              The same with: http://www.smartclient.com/smartgwte...g_stock_quotes
              you are subscribing and immediately generating the updates afterwards, which are based on RPCManager.sendRequest(request); . So the same, or ?
              Code:
              [LIST][*]// receive messages from the stockQuotes channel and update data grid[*]Messaging.subscribe("stockQuotes" + startParameter, new MessagingCallback() {[*]@Override[*]public void execute(Object data) {[*]updateStockQuotes(data);[*]}[*]});[*]generateUpdates(startParameter, generateUpdatesButton);[/LIST]
              Last edited by edulid; 30 Sep 2016, 01:23.

              Comment


                #8
                The difference is that there are dozens of updates generated, so missing the first one wouldn't change observed behavior.

                But to clarify, there are two available callbacks: the MessagingCallback for receiving messages, and the ability to be called when the subscription itself completes, via setConnectionUpCallback(). This latter callback is the one to use if your application needs to be sure to receive messages it sends to itself right after subscription.

                Comment


                  #9
                  Originally posted by Isomorphic View Post
                  The difference is that there are dozens of updates generated, so missing the first one wouldn't change observed behavior.

                  But to clarify, there are two available callbacks: the MessagingCallback for receiving messages, and the ability to be called when the subscription itself completes, via setConnectionUpCallback(). This latter callback is the one to use if your application needs to be sure to receive messages it sends to itself right after subscription.
                  Thank you! This is what I was missing.
                  I think you should update the showcase to show this behavior, as this would be helpful and is "more correct", since you are sure you get all the messages.

                  Comment


                    #10
                    I am not sure if the method is the one I am looking for, or maybe I understand the javadocs incorrectly:
                    Code:
                    Called when the messaging connection allowing the server to send messages to the client is established - whether that's the result of an initial connect() or a re-establishment after it is severed.
                    1. So if I have two subscriptions to different channels, the callback would be called only once ? At the first connection?

                    2. On case of a re-establishment of the connection: will this be called again? So the method will be called more than once in this case ?

                    I thought of a callback message e.g. :
                    Code:
                    Messaging.subscribe(channel, new MessagingCallback() {
                                @Override
                                public void execute(Object data) {
                                    // I get a message
                                }
                                @Override
                                public void subscriptionSuccessful() {
                                   // the subscription was successful,
                                   // here I would call the DMIMethod, since we are already subscribed.
                               }
                            },
                    
                    );

                    Comment


                      #11
                      Isomorphic am I understanding something wrong ?

                      Comment


                        #12
                        The callback MessagingConnectionUpCallback is fired:
                        1. after a subscription to a channel, or to a second channel when one is already subscribed to one channel
                        2. when the connection is automatically re-established (as happens periodically - every two minutes by default).

                        So, answering your first question, if you have two subscriptions, the callback will be called twice, once per subscription, specifically each time one subscription has been successfully stablished.
                        And regarding your second question, yes, the callback will be fired more than once, in fact it will be called periodically (every two minutes by default).

                        This is how the performCustomOperation could be called when using MessagingConnectionUpCallback, although you probably should include some extra code to avoid sending the customOperation more than once:
                        Code:
                               Messaging.setConnectionUpCallback(new MessagingConnectionUpCallback() {
                                    @Override
                                    public void execute() {
                                         Record rec = new Record();
                                         rec.setAttribute("channel", ti.getValue());
                                         DataSource.get("testingDS").performCustomOperation("testMethod", rec, null);
                                    }
                               });
                        This code can be included right before declaring the button ClickHandler in your onModuleLoad() method.


                        Comment

                        Working...
                        X