vitalyster/SharpXMPP

Message with custom fields/attributes

Closed this issue · 7 comments

Hi.,

I am looking to add some custom fields into XMPPMessage. Its pretty simple to modify the project and add custom fields but is there any way out there to add custom field with the existing XMPPMessage class and use it without modifying the code. Or is there any possibility to send message by setting custom attributes and process the attribute value on receiving end.
Like this

        var message = new XMPPMessages
        {   
            ID=Guid.NewGuid().ToString(),
            Text = "Hi",
            To = new JID("34@abc.com")
        };
        message.SetAttributeValue("type", "Urgent");
      Client.Send(message)
  1. XMPPMessage is a subclass of System.Xml.Linq.XElement, you can use any LINQ to XML methods to set attributes and/or child items.
  2. While technically you can add random values, it is much better to prefix your custom elements in your custom namespace.
    message element is defined in jabber:client namespace, full representation
    of message looks like this:
    <message xmlns='jabber:client' type='chat' to='34@abc.com'><body>Hi!</body></message>
    jabber:client namespace had predefined type values: normal, chat, groupchat, headline, error (see https://tools.ietf.org/html/rfc6121#section-5.2.2). We can use these values without prefix because they are defined in root namespace. If you want to use custom type, then it should have a prefix like this:
    <message xmlns='jabber:client' type='chat' to='34@abc.com' x:type='Urgent' xmlns:x='my:custom:namespace:prefix'><body>Hi!</body></message> - we added new namespace and this will allow other clients and servers understand and transfer your message correctly. If you will add elements without your own namespace and prefix - it will give you errors.
  3. LINQ to XML code example: SetAttributeValue(XNamespace.Get('my:custom:namespace') + 'type', 'Urgent') - this will add correct namespace and prefix your elements with it

Hi,

I am doing this task using setting elements. It is waking fine at my app plus with external third party xmpp clients. I just wanted to know is this approach is perfect or I am violating the standards.


ON SENDING SIDE

var message = new XMPPMessages
{
ID=Guid.NewGuid().ToString(),
Text = "Hello chat",
To = new JID("345@abc.com")
};
message.SetElementValue("MessageType", MessageType.Audio);
message.SetElementValue("UserName","Adam");
message.SetAttributeValue("type", "Urgent");
Client.Send(message);


ON RECEIVING END

private void Client_Message(XmppConnection sender, XMPPMessage e)
{
var MessageType = (MessageType) Enum.Parse
(typeof(MessageType), e.Element("MessageType").Value);

        var UserName =   e.Element("UserName").Value;
          switch (MessageType)
        {
            case global::MessageType.MUCInitation:
                break;
            case global::MessageType.Audio:
                break;
            case global::MessageType.Video:
                break;
            case global::MessageType.Text:
                break;
            case global::MessageType.AudioCall:
                break;
            case global::MessageType.VideoCall:
                break;
            default:
                break;
        }
    }

public enum MessageType
{
MUCInitation , Audio , Video , Text , AudioCall , VideoCall
}

That was exactly what I have described: you need to set namespace for your objects, otherwise you are sending invalid xml.

Hi,

here is my modified code but I am not able to get the value of custom attribute at receiving end.
Please guide what I am missing.

ON SENDING SIDE

message.SetAttributeValue(XNamespace.Get("my:app:namespace") + "username", "guest");


ON RECEIVING END

var userName = e.Element(XNamespace.Get("my:app:namespace") + "username");

Hi,

I changed to SetElementValue and it works. Just guide me is this approach is fine.

ON SENDING SIDE
message.SetElementValue(XNamespace.Get("my:app:namespace") + "username", "guest");

ON RECEIVING END
var userName = e.Element(XNamespace.Get("my:app:namespace") + "username");

Perfect! That is the way how XMPP can be extended in general. You will be able to read these values correctly in any language, not only C#, that is why namespaces matter

Thanks and highly appreciated your support/help and patience.

Thanks