Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Component.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading.Tasks;
5using System.Xml;
7using Waher.Events;
9
11{
16 {
20 protected SortedDictionary<string, bool> features = new SortedDictionary<string, bool>();
21
25 protected readonly object synchObject = new object();
26
27 private readonly Dictionary<string, EventHandlerAsync<IqEventArgs>> iqGetHandlers = new Dictionary<string, EventHandlerAsync<IqEventArgs>>();
28 private readonly Dictionary<string, EventHandlerAsync<IqEventArgs>> iqSetHandlers = new Dictionary<string, EventHandlerAsync<IqEventArgs>>();
29 private readonly Dictionary<string, EventHandlerAsync<MessageEventArgs>> messageHandlers = new Dictionary<string, EventHandlerAsync<MessageEventArgs>>();
30 private readonly Dictionary<string, EventHandlerAsync<PresenceEventArgs>> presenceHandlers = new Dictionary<string, EventHandlerAsync<PresenceEventArgs>>();
31 private readonly IqResponses responses = new IqResponses(TimeSpan.FromMinutes(1));
32 private readonly XmppServer server;
33 private readonly CaseInsensitiveString subdomain;
34 private readonly CaseInsensitiveString subdomainSuffixed;
35 private readonly XmppAddress mainDomain;
36 private readonly string name;
37
44 public Component(XmppServer Server, string Subdomain, string Name)
46 {
47 }
48
56 {
57 this.subdomain = Subdomain;
58 this.subdomainSuffixed = Subdomain + ".";
59 this.name = Name;
60 this.server = Server;
61 this.mainDomain = new XmppAddress(this.subdomainSuffixed + this.server.Domain);
62
63 if (!string.IsNullOrEmpty(Subdomain) && !(this.server is null))
64 {
65 if (!this.server.RegisterComponent(this))
66 throw new InvalidOperationException("A component with subdomain " + Subdomain + " has already been registered.");
67 }
68
69 this.RegisterIqGetHandler("query", XmppServer.DiscoveryNamespace, this.DiscoveryQueryGet, true); // XEP-0030
70 this.RegisterIqGetHandler("query", XmppServer.DiscoveryItemsNamespace, this.DiscoveryQueryItemsGet, true); // XEP-0030
71 }
72
76 public CaseInsensitiveString Subdomain => this.subdomain;
77
81 public CaseInsensitiveString SubdomainSuffixed => this.subdomainSuffixed;
82
86 public XmppAddress MainDomain => this.mainDomain;
87
91 public string Name => this.name;
92
96 public XmppServer Server => this.server;
97
101 public virtual void Dispose()
102 {
103 if (!string.IsNullOrEmpty(this.subdomain) && !(this.server is null))
104 this.server.UnregisterComponent(this);
105
106 this.UnregisterIqGetHandler("query", XmppServer.DiscoveryNamespace, this.DiscoveryQueryGet, true); // XEP-0030
107
108 this.responses.Dispose();
109 }
110
115 public virtual bool SupportsAccounts => false;
116
123 public bool IsComponentDomain(CaseInsensitiveString Domain, bool IncludeAlternativeDomains)
124 {
125 if (Domain == this.subdomainSuffixed + this.server.Domain)
126 return true;
127
128 if (IncludeAlternativeDomains && !(this.server.AlternativeDomains is null))
129 {
130 foreach (CaseInsensitiveString s in this.server.AlternativeDomains)
131 {
132 if (Domain == this.subdomainSuffixed + s)
133 return true;
134 }
135 }
136
137 return false;
138 }
139
140 #region Stanzas
141
149 public void RegisterIqGetHandler(string LocalName, string Namespace, EventHandlerAsync<IqEventArgs> Handler, bool PublishNamespaceAsFeature)
150 {
151 this.RegisterIqHandler(this.iqGetHandlers, LocalName, Namespace, Handler, PublishNamespaceAsFeature);
152 }
153
161 public void RegisterIqSetHandler(string LocalName, string Namespace, EventHandlerAsync<IqEventArgs> Handler, bool PublishNamespaceAsFeature)
162 {
163 this.RegisterIqHandler(this.iqSetHandlers, LocalName, Namespace, Handler, PublishNamespaceAsFeature);
164 }
165
166 private void RegisterIqHandler(Dictionary<string, EventHandlerAsync<IqEventArgs>> Handlers, string LocalName, string Namespace, EventHandlerAsync<IqEventArgs> Handler,
167 bool PublishNamespaceAsFeature)
168 {
169 string Key = LocalName + " " + Namespace;
170
171 lock (this.synchObject)
172 {
173 if (Handlers.ContainsKey(Key))
174 throw new ArgumentException("Handler already registered.", nameof(LocalName));
175
176 Handlers[Key] = Handler;
177
178 if (PublishNamespaceAsFeature)
179 this.features[Namespace] = true;
180 }
181 }
182
190 public void RegisterMessageHandler(string LocalName, string Namespace, EventHandlerAsync<MessageEventArgs> Handler, bool PublishNamespaceAsFeature)
191 {
192 string Key = LocalName + " " + Namespace;
193
194 lock (this.synchObject)
195 {
196 if (this.messageHandlers.ContainsKey(Key))
197 throw new ArgumentException("Handler already registered.", nameof(LocalName));
198
199 this.messageHandlers[Key] = Handler;
200
201 if (PublishNamespaceAsFeature)
202 this.features[Namespace] = true;
203 }
204 }
205
213 public void RegisterPresenceHandler(string LocalName, string Namespace, EventHandlerAsync<PresenceEventArgs> Handler, bool PublishNamespaceAsFeature)
214 {
215 string Key = LocalName + " " + Namespace;
216
217 lock (this.synchObject)
218 {
219 if (this.presenceHandlers.ContainsKey(Key))
220 throw new ArgumentException("Handler already registered.", nameof(LocalName));
221
222 this.presenceHandlers[Key] = Handler;
223
224 if (PublishNamespaceAsFeature)
225 this.features[Namespace] = true;
226 }
227 }
228
233 public void RegisterFeature(string Namespace)
234 {
235 lock (this.synchObject)
236 {
237 this.features[Namespace] = true;
238 }
239 }
240
249 public bool UnregisterIqGetHandler(string LocalName, string Namespace, EventHandlerAsync<IqEventArgs> Handler, bool RemoveNamespaceAsFeature)
250 {
251 return this.UnregisterIqHandler(this.iqGetHandlers, LocalName, Namespace, Handler, RemoveNamespaceAsFeature);
252 }
253
262 public bool UnregisterIqSetHandler(string LocalName, string Namespace, EventHandlerAsync<IqEventArgs> Handler, bool RemoveNamespaceAsFeature)
263 {
264 return this.UnregisterIqHandler(this.iqSetHandlers, LocalName, Namespace, Handler, RemoveNamespaceAsFeature);
265 }
266
267 private bool UnregisterIqHandler(Dictionary<string, EventHandlerAsync<IqEventArgs>> Handlers, string LocalName, string Namespace, EventHandlerAsync<IqEventArgs> Handler,
268 bool RemoveNamespaceAsFeature)
269 {
270 string Key = LocalName + " " + Namespace;
271
272 lock (this.synchObject)
273 {
274 if (!Handlers.TryGetValue(Key, out EventHandlerAsync<IqEventArgs> h))
275 return false;
276
277 if (h != Handler)
278 return false;
279
280 Handlers.Remove(Key);
281
282 if (RemoveNamespaceAsFeature)
283 this.features.Remove(Namespace);
284 }
285
286 return true;
287 }
288
297 public bool UnregisterMessageHandler(string LocalName, string Namespace, EventHandlerAsync<MessageEventArgs> Handler, bool RemoveNamespaceAsFeature)
298 {
299 string Key = LocalName + " " + Namespace;
300
301 lock (this.synchObject)
302 {
303 if (!this.messageHandlers.TryGetValue(Key, out EventHandlerAsync<MessageEventArgs> h))
304 return false;
305
306 if (h != Handler)
307 return false;
308
309 this.messageHandlers.Remove(Key);
310
311 if (RemoveNamespaceAsFeature)
312 this.features.Remove(Namespace);
313 }
314
315 return true;
316 }
317
326 public bool UnregisterPresenceHandler(string LocalName, string Namespace, EventHandlerAsync<PresenceEventArgs> Handler, bool RemoveNamespaceAsFeature)
327 {
328 string Key = LocalName + " " + Namespace;
329
330 lock (this.synchObject)
331 {
332 if (!this.presenceHandlers.TryGetValue(Key, out EventHandlerAsync<PresenceEventArgs> h))
333 return false;
334
335 if (h != Handler)
336 return false;
337
338 this.presenceHandlers.Remove(Key);
339
340 if (RemoveNamespaceAsFeature)
341 this.features.Remove(Namespace);
342 }
343
344 return true;
345 }
346
351 public void UnregisterFeature(string Namespace)
352 {
353 lock (this.synchObject)
354 {
355 this.features.Remove(Namespace);
356 }
357 }
358
369 public async Task<bool> IQ(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
370 {
371 Dictionary<string, EventHandlerAsync<IqEventArgs>> Handlers;
372 EventHandlerAsync<IqEventArgs> h = null;
373 string Key;
374
375 switch (Type)
376 {
377 case "get":
378 if (this.responses.TryGet(From.Address, Id, out string ResponseXml, out bool Ok))
379 {
380 if (Ok)
381 return await Sender.IqResult(Id, From, To, ResponseXml);
382 else
383 return await Sender.IqError(Id, From, To, ResponseXml);
384 }
385 else
386 Handlers = this.iqGetHandlers;
387 break;
388
389 case "set":
390 if (this.responses.TryGet(From.Address, Id, out ResponseXml, out Ok))
391 {
392 if (Ok)
393 return await Sender.IqResult(Id, From, To, ResponseXml);
394 else
395 return await Sender.IqError(Id, From, To, ResponseXml);
396 }
397 else
398 Handlers = this.iqSetHandlers;
399 break;
400
401 case "result":
402 case "error":
403 return await this.server.ProcessResponse(Type, Id, To, From, Language, true, false, Stanza, Sender);
404
405 default:
406 if (Sender is null)
407 return false;
408 else
409 return !(await Sender.IqErrorBadRequest(Id, From, To, "Invalid type.", "en") is null);
410 }
411
412 IqEventArgs e = new IqEventArgs(Sender, Stanza.StanzaElement, Id, Type, To, From, Language, this.responses);
413
414 lock (this.synchObject)
415 {
416 foreach (XmlNode N in Stanza.StanzaElement.ChildNodes)
417 {
418 if (!(N is XmlElement E))
419 continue;
420
421 Key = E.LocalName + " " + E.NamespaceURI;
422 if (Handlers.TryGetValue(Key, out h))
423 {
424 e.Query = E;
425 break;
426 }
427 else
428 h = null;
429 }
430 }
431
432 if (h is null)
433 {
434 if (Sender is null)
435 return false;
436 else
437 return !(await Sender.IqError(Id, From, To, "cancel", "<feature-not-implemented xmlns='" + XmppServer.StanzaNamespace + "'/>", string.Empty, string.Empty) is null);
438 }
439 else
440 {
441 try
442 {
443 await h(this, e);
444 return true;
445 }
446 catch (Exception ex)
447 {
448 if (Sender is null)
449 return false;
450 else
451 return !(await Sender.IqError(Id, From, To, ex) is null);
452 }
453 }
454 }
455
466 public Task<bool> IQ(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
467 {
468 return this.IQ(Type, Id, To, From, Language, XmppServer.ToStanza("iq", Type, Id, To, From, Language, ContentXml), Sender);
469 }
470
481 public async Task<bool> Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
482 {
483 MessageEventArgs e = new MessageEventArgs(Sender, Stanza.StanzaElement, Id, Type, To, From, Language);
484 EventHandlerAsync<MessageEventArgs> h = null;
485 string Key;
486
487 lock (this.synchObject)
488 {
489 foreach (XmlNode N in Stanza.StanzaElement.ChildNodes)
490 {
491 if (!(N is XmlElement E))
492 continue;
493
494 Key = E.LocalName + " " + E.NamespaceURI;
495 if (this.messageHandlers.TryGetValue(Key, out h))
496 {
497 e.Content = E;
498 break;
499 }
500 else
501 h = null;
502 }
503 }
504
505 try
506 {
507 if (h is null)
508 await this.MessageNoHandlerReceived(e);
509 else
510 await h(this, e);
511 }
512 catch (Exception ex)
513 {
514 if (!(Sender is null))
515 await (Sender?.MessageError(Id, From, To, ex) ?? Task.CompletedTask);
516 }
517
518 return true;
519 }
520
526 {
527 return Task.CompletedTask;
528 }
529
540 public Task<bool> Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
541 {
542 return this.Message(Type, Id, To, From, Language, XmppServer.ToStanza("message", Type, Id, To, From, Language, ContentXml), Sender);
543 }
544
554 //public Task<bool> Presence(string Type, string Id, CaseInsensitiveString From, string Language, Stanza Stanza, ISender Sender)
555 //{
556 // // TODO: Component presence
557 // return Task.FromResult(true);
558 //}
559
570 public async Task<bool> Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
571 {
572 PresenceEventArgs e = new PresenceEventArgs(Sender, Type, Id, To, From, Language, Stanza, null);
573 EventHandlerAsync<PresenceEventArgs> h = null;
574 string Key;
575
576 lock (this.synchObject)
577 {
578 foreach (XmlNode N in Stanza.StanzaElement.ChildNodes)
579 {
580 if (!(N is XmlElement E))
581 continue;
582
583 Key = E.LocalName + " " + E.NamespaceURI;
584 if (this.presenceHandlers.TryGetValue(Key, out h))
585 {
586 e.Content = E;
587 break;
588 }
589 else
590 h = null;
591 }
592 }
593
594 try
595 {
596 if (h is null)
597 await this.PresenceNoHandlerReceived(e);
598 else
599 await h(this, e);
600 }
601 catch (Exception ex)
602 {
603 if (!(Sender is null))
604 await (Sender?.PresenceError(Id, From, To, ex) ?? Task.CompletedTask);
605 }
606
607 return true;
608 }
609
615 {
616 return Task.CompletedTask;
617 }
618
629 public Task<bool> Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
630 {
631 return this.Presence(Type, Id, To, From, Language, XmppServer.ToStanza("presence", Type, Id, To, From, Language, ContentXml), Sender);
632 }
633
639 protected static string InnerXmlNoJabberNamespace(XmlElement Xml)
640 {
641 if (Xml is null)
642 return string.Empty;
643
644 string s = Xml.OuterXml;
645 int i = s.IndexOf('>');
646 int j = s.LastIndexOf('<');
647
648 if (j <= i)
649 return string.Empty;
650
651 return s.Substring(i + 1, j - i - 1);
652 }
653
654 #endregion
655
656 #region Discovery XEP-0030
657
663 protected virtual async Task DiscoveryQueryGet(object Sender, IqEventArgs e)
664 {
665 XmlElement E = e.Query;
666
667 if (e.To.HasAccount && (!this.SupportsAccounts || !await this.SupportsAccount(e.To.Account)))
668 {
669 await e.IqErrorItemNotFound(e.To, "Item not found.", "en");
670 return;
671 }
672
673 string Node = XML.Attribute(E, "node");
674 if (!string.IsNullOrEmpty(Node) && !await this.SupportsNode(Node))
675 {
676 await e.IqErrorItemNotFound(e.To, "Node not found.", "en");
677 return;
678 }
679
680 StringBuilder Xml = new StringBuilder();
681
682 Xml.Append("<query xmlns='");
683 Xml.Append(XmppServer.DiscoveryNamespace);
684 Xml.Append("'>");
685
686 await this.AppendServiceDiscoveryIdentities(Xml, e, Node);
687
688 if (string.IsNullOrEmpty(e.To.Account) && string.IsNullOrEmpty(Node))
689 {
690 lock (this.synchObject)
691 {
692 foreach (string Feature in this.features.Keys)
693 {
694 Xml.Append("<feature var='");
695 Xml.Append(XML.Encode(Feature));
696 Xml.Append("'/>");
697 }
698 }
699 }
700
701 await this.AppendServiceDiscoveryFeatures(Xml, e, Node);
702
703 Xml.Append("</query>");
704
705 await e.IqResult(Xml.ToString(), e.To);
706 }
707
713 protected virtual Task<bool> SupportsAccount(string Account)
714 {
715 return Task.FromResult(false);
716 }
717
723 protected virtual Task<bool> SupportsNode(string Node)
724 {
725 return Task.FromResult(false);
726 }
727
733 protected virtual async Task DiscoveryQueryItemsGet(object Sender, IqEventArgs e)
734 {
735 XmlElement E = e.Query;
736
737 if (e.To.HasAccount && (!this.SupportsAccounts || !await this.SupportsAccount(e.To.Account)))
738 {
739 await e.IqErrorItemNotFound(e.To, "Item not found.", "en");
740 return;
741 }
742
743 string Node = XML.Attribute(E, "node");
744 if (!string.IsNullOrEmpty(Node) && !await this.SupportsNode(Node))
745 {
746 await e.IqErrorItemNotFound(e.To, "Node not found.", "en");
747 return;
748 }
749
750 StringBuilder Xml = new StringBuilder();
751
752 Xml.Append("<query xmlns='");
754 Xml.Append("'>");
755
756 await this.AppendItemInformation(Xml, e, Node);
757
758 Xml.Append("</query>");
759
760 await e.IqResult(Xml.ToString(), e.To);
761 }
762
769 protected virtual Task AppendServiceDiscoveryIdentities(StringBuilder Xml, IqEventArgs e, string Node)
770 {
771 return Task.CompletedTask;
772 }
773
780 protected virtual Task AppendServiceDiscoveryFeatures(StringBuilder Xml, IqEventArgs e, string Node)
781 {
782 return Task.CompletedTask;
783 }
784
791 protected virtual Task AppendItemInformation(StringBuilder Xml, IqEventArgs e, string Node)
792 {
793 return Task.CompletedTask;
794 }
795
796 #endregion
797
798 #region ISender
799
808 public virtual Task<string> IqError(string Id, XmppAddress To, XmppAddress From, Exception ex)
809 {
810 return Task.FromResult(string.Empty); // Do nothing by default.
811 }
812
821 public virtual Task<bool> IqError(string Id, XmppAddress To, XmppAddress From, string ErrorXml)
822 {
823 return Task.FromResult(true); // Do nothing by default.
824 }
825
834 public virtual Task<bool> IqResult(string Id, XmppAddress To, XmppAddress From, string ResultXml)
835 {
836 return Task.FromResult(true); // Do nothing by default.
837 }
838
847 public virtual Task<bool> PresenceError(string Id, XmppAddress To, XmppAddress From, Exception ex)
848 {
849 return Task.FromResult(true); // Do nothing by default.
850 }
851
860 public virtual Task<bool> PresenceError(string Id, XmppAddress To, XmppAddress From, string ErrorXml)
861 {
862 return Task.FromResult(true); // Do nothing by default.
863 }
864
874 public virtual Task<bool> Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
875 {
876 return Task.FromResult(true); // Do nothing by default.
877 }
878
888 public virtual Task<bool> Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
889 {
890 return Task.FromResult(true); // Do nothing by default.
891 }
892
901 public virtual Task<bool> MessageError(string Id, XmppAddress To, XmppAddress From, Exception ex)
902 {
903 return Task.FromResult(true); // Do nothing by default.
904 }
905
906 #endregion
907
908 }
909}
Helps with common XML-related tasks.
Definition: XML.cs:19
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
Definition: XML.cs:914
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:27
Base class for components.
Definition: Component.cs:16
bool UnregisterMessageHandler(string LocalName, string Namespace, EventHandlerAsync< MessageEventArgs > Handler, bool RemoveNamespaceAsFeature)
Unregisters a message handler.
Definition: Component.cs:297
virtual Task AppendServiceDiscoveryIdentities(StringBuilder Xml, IqEventArgs e, string Node)
Appends component identities, as defined in XEP-0030, to a discovery response.
Definition: Component.cs:769
void RegisterIqSetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool PublishNamespaceAsFeature)
Registers an IQ-Set handler.
Definition: Component.cs:161
CaseInsensitiveString Subdomain
Subdomain name.
Definition: Component.cs:76
Component(XmppServer Server, CaseInsensitiveString Subdomain, string Name)
Base class for components.
Definition: Component.cs:55
CaseInsensitiveString SubdomainSuffixed
Subdomain name, suffixed with a period (.).
Definition: Component.cs:81
virtual Task< bool > PresenceError(string Id, XmppAddress To, XmppAddress From, Exception ex)
Sends an Presence Error stanza.
Definition: Component.cs:847
virtual Task< bool > IqError(string Id, XmppAddress To, XmppAddress From, string ErrorXml)
Sends an IQ Error stanza.
Definition: Component.cs:821
bool UnregisterPresenceHandler(string LocalName, string Namespace, EventHandlerAsync< PresenceEventArgs > Handler, bool RemoveNamespaceAsFeature)
Unregisters a presence handler.
Definition: Component.cs:326
void RegisterIqGetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool PublishNamespaceAsFeature)
Registers an IQ-Get handler.
Definition: Component.cs:149
static string InnerXmlNoJabberNamespace(XmlElement Xml)
Removes the jabber namespace from the outer XML of an element.
Definition: Component.cs:639
Task< bool > IQ(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
IQ stanza.
Definition: Component.cs:466
void RegisterPresenceHandler(string LocalName, string Namespace, EventHandlerAsync< PresenceEventArgs > Handler, bool PublishNamespaceAsFeature)
Registers a presence handler.
Definition: Component.cs:213
virtual async Task DiscoveryQueryGet(object Sender, IqEventArgs e)
Get handler for Service Discovery query (XEP-0030).
Definition: Component.cs:663
virtual Task< bool > PresenceError(string Id, XmppAddress To, XmppAddress From, string ErrorXml)
Sends an Presence Error stanza.
Definition: Component.cs:860
virtual Task MessageNoHandlerReceived(MessageEventArgs e)
Message without corresponding handler received.
Definition: Component.cs:525
virtual async Task DiscoveryQueryItemsGet(object Sender, IqEventArgs e)
Get handler for Service Discovery items query (XEP-0030).
Definition: Component.cs:733
virtual Task< bool > MessageError(string Id, XmppAddress To, XmppAddress From, Exception ex)
Sends a message error.
Definition: Component.cs:901
Task< bool > Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
Presence stanza.
Definition: Component.cs:629
XmppAddress MainDomain
Main/principal domain address
Definition: Component.cs:86
readonly object synchObject
Synchronization object for thread-safe access to internal structures.
Definition: Component.cs:25
virtual Task< bool > Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
Presence stanza.
Definition: Component.cs:874
virtual Task AppendItemInformation(StringBuilder Xml, IqEventArgs e, string Node)
Appends item information to a service item description response.
Definition: Component.cs:791
virtual Task AppendServiceDiscoveryFeatures(StringBuilder Xml, IqEventArgs e, string Node)
Appends custom service descriptions.
Definition: Component.cs:780
bool IsComponentDomain(CaseInsensitiveString Domain, bool IncludeAlternativeDomains)
Checks if a domain is the component domain, or optionally, an alternative component domain.
Definition: Component.cs:123
virtual void Dispose()
IDisposable.Dispose
Definition: Component.cs:101
async Task< bool > Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
Message stanza.
Definition: Component.cs:481
async Task< bool > IQ(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
IQ stanza.
Definition: Component.cs:369
virtual bool SupportsAccounts
If the component supports accounts (true), or if the subdomain name is the only valid address.
Definition: Component.cs:115
virtual Task< bool > Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
Message stanza.
Definition: Component.cs:888
async Task< bool > Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
Presence stanza.
Definition: Component.cs:570
XmppServer Server
XMPP Server.
Definition: Component.cs:96
virtual Task PresenceNoHandlerReceived(PresenceEventArgs e)
Presence stanza without a corresponding handler received.
Definition: Component.cs:614
virtual Task< bool > IqResult(string Id, XmppAddress To, XmppAddress From, string ResultXml)
Sends an IQ Result stanza.
Definition: Component.cs:834
bool UnregisterIqGetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool RemoveNamespaceAsFeature)
Unregisters an IQ-Get handler.
Definition: Component.cs:249
virtual Task< bool > SupportsNode(string Node)
If the component supports a named node.
Definition: Component.cs:723
virtual Task< bool > SupportsAccount(string Account)
If the component supports a named account.
Definition: Component.cs:713
bool UnregisterIqSetHandler(string LocalName, string Namespace, EventHandlerAsync< IqEventArgs > Handler, bool RemoveNamespaceAsFeature)
Unregisters an IQ-Set handler.
Definition: Component.cs:262
void UnregisterFeature(string Namespace)
Unregisters a feature.
Definition: Component.cs:351
virtual Task< string > IqError(string Id, XmppAddress To, XmppAddress From, Exception ex)
Sends an IQ Error stanza.
Definition: Component.cs:808
Task< bool > Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
Message stanza.
Definition: Component.cs:540
void RegisterMessageHandler(string LocalName, string Namespace, EventHandlerAsync< MessageEventArgs > Handler, bool PublishNamespaceAsFeature)
Registers a message handler.
Definition: Component.cs:190
SortedDictionary< string, bool > features
Features supported by component.
Definition: Component.cs:20
Component(XmppServer Server, string Subdomain, string Name)
Base class for components.
Definition: Component.cs:44
void RegisterFeature(string Namespace)
Registers a feature.
Definition: Component.cs:233
Event arguments for IQ queries.
Definition: IqEventArgs.cs:12
Task IqResult(string Xml, string From)
Returns a response to the current request.
Definition: IqEventArgs.cs:113
Task IqErrorItemNotFound(XmppAddress From, string ErrorText, string Language)
Returns a item-not-found error.
Definition: IqEventArgs.cs:201
XmlElement Query
Query element, if found, null otherwise.
Definition: IqEventArgs.cs:70
XmppAddress To
To address attribute
Definition: IqEventArgs.cs:88
Maintains a set of IQ responses, for a limited time.
Definition: IqResponses.cs:18
Presence information event arguments.
Contains information about a stanza.
Definition: Stanza.cs:10
XmlElement StanzaElement
Stanza element.
Definition: Stanza.cs:114
Contains information about one XMPP address.
Definition: XmppAddress.cs:9
bool HasAccount
If the address has an account part.
Definition: XmppAddress.cs:167
CaseInsensitiveString Address
XMPP Address
Definition: XmppAddress.cs:37
CaseInsensitiveString Account
Account
Definition: XmppAddress.cs:124
const string DiscoveryItemsNamespace
http://jabber.org/protocol/disco#items (XEP-0030)
Definition: XmppServer.cs:133
const string DiscoveryNamespace
http://jabber.org/protocol/disco#info (XEP-0030)
Definition: XmppServer.cs:128
const string StanzaNamespace
urn:ietf:params:xml:ns:xmpp-stanzas (RFC 6120)
Definition: XmppServer.cs:98
Represents a case-insensitive string.
Interface for components.
Definition: IComponent.cs:10
Interface for senders of stanzas.
Definition: ISender.cs:10
Task< string > IqError(string Id, XmppAddress To, XmppAddress From, Exception ex)
Sends an IQ Error stanza.
Task< bool > IqResult(string Id, XmppAddress To, XmppAddress From, string ResultXml)
Sends an IQ Result stanza.