Thanks again. I looking again at a solution to this problem, I have now managed to either break my application or expose an existing flaw that I had not realised was there. I am not sure which one at the moment. If you will bear with me, I will try to explain what I am observing and that this is questioning my understanding of how Matrix does Iq filters.
The application I am building is a pair of applications that exchange messages bi-directionally - that is both ends are the service consumer and provider for the same message types.
On an originating end, I do something like:
Here the method "DispatcherResponse" will then process a "success" variant of the "Dispatcher" message.
On the receiving end I have a method (using your callback filter class) that accepts Dispatcher requests and then (after the real work) send the success response. Something like this:
To complete the picture, back on the originating end, the DispatcherResponse, looks like this:
What I am seeing in my logs is that the DispatcherCallback (on the originator-side) is picking up the success response and not the DispatcherResponse method. I have been using a variation of this code for some weeks, but I have only just added enough diagnostics to see this behaviour (or I may have recently added this "feature").
Back to the questions:
1. How does Matrix make sure that the correct (or intended) method is called? Does setting up the Iq filter take precedence over the main On_Iq?
2. How does Matrix correlate requests with responses? Here the view has to be that it is matching message IDs. Is this the case?
3. If it is matching message IDs, how does one circumvent a pair of clients each generating its own (unique to it) but not unique across clients? I know I can set the ID with a GUID, but is this accepted practice?
4. The clState.Client.IqFilter.SendIq method has two separate implementations, one that takes the callback and the other the "Object state". What is the latter for and will this help?
Thanks again.
John
The application I am building is a pair of applications that exchange messages bi-directionally - that is both ends are the service consumer and provider for the same message types.
On an originating end, I do something like:
- void sendMessage(string destination, string filename, string contents)
- {
- {
- Type = Matrix.Xmpp.IqType.set,
- To = destination + "/" + clState.Resource,
- Dispatcher = new Dispatcher { SenderMAN = clState.Username, RecipientMAN = destination, Filename = filename, MessageBody = fu.getBase64Contents(contents) }
- };
- // we pass the filename as state object to the IqFilter
- clState.Client.IqFilter.SendIq(diq, DispatcherResponse,filename);
- }
Here the method "DispatcherResponse" will then process a "success" variant of the "Dispatcher" message.
On the receiving end I have a method (using your callback filter class) that accepts Dispatcher requests and then (after the real work) send the success response. Something like this:
- private void DispatcherCallback(object sender, IqEventArgs e)
- {
- {
- var dispatcher = e.Iq.Query as Dispatcher;
- // do some interesting work
- //now send response
- {
- Id = e.Iq.Id, //used to correlate with the request !!!
- To = e.Iq.From,
- Type = Matrix.Xmpp.IqType.result,
- Dispatcher = new Dispatcher { Filename = dispatcher.Filename, MessageBody = "success", SenderMAN = e.Iq.From.ToString(), RecipientMAN = e.Iq.To.ToString() }
- };
- // send the response
- clState.Client.Send(diq);
- }
- else
- {
- logger.Error("Dispatcher callback Iq received, but can't marshal {0}", e.Iq.ToString());
- }
- }
To complete the picture, back on the originating end, the DispatcherResponse, looks like this:
- private void DispatcherResponse(object sender, Matrix.Xmpp.Client.IqEventArgs e)
- {
- var iq = e.Iq;
- if (iq.Type == Matrix.Xmpp.IqType.result)
- {
- var dispatcher = iq.Element<Dispatcher>();
- if (dispatcher != null)
- {
- //I now know I have the response and so clean-up
- }
- else
- {
- logger.Error("Dispatcher response Iq received, but can't marshal {0}", e.Iq.ToString());
- }
- }
- else
- {
- logger.Error("Dispatcher response Error received {0}", e.Iq.ToString());
- }
- }
What I am seeing in my logs is that the DispatcherCallback (on the originator-side) is picking up the success response and not the DispatcherResponse method. I have been using a variation of this code for some weeks, but I have only just added enough diagnostics to see this behaviour (or I may have recently added this "feature").
Back to the questions:
1. How does Matrix make sure that the correct (or intended) method is called? Does setting up the Iq filter take precedence over the main On_Iq?
2. How does Matrix correlate requests with responses? Here the view has to be that it is matching message IDs. Is this the case?
3. If it is matching message IDs, how does one circumvent a pair of clients each generating its own (unique to it) but not unique across clients? I know I can set the ID with a GUID, but is this accepted practice?
4. The clState.Client.IqFilter.SendIq method has two separate implementations, one that takes the callback and the other the "Object state". What is the latter for and will this help?
Thanks again.
John