Good C# XMPP Library supporting Group Chat and TLS

2019-03-21 15:52发布

问题:

So I have been struggling with finding a decent C# library to use with XMPP that supports either SSL or TSL encryption between the clients and the server. I am hoping that someone can recommend I library that meets some of my needs and is fairly well supported/documented. Also perhaps someone can confirm my suspicions about some of the libraries I've already tried.

My first attempt used Soapbox Studio SDK. Found here from Conversant, however from what I can tell they only support SASL authentication. I attempted to contact them but received no response and there forum appeared to be not working as I could not post my question on their forum. Perhaps I am wrong about my SSL assumption with Soapbox's library, which would be great if someone could correct me because that is the library that I would prefer to use.

I next moved on to Matrix which is the successor to agXmpp. After several days trolling their message boards and going through their sample applications I cannot mange to even create a Group Chat on my openfire server. Almost all of the related questions posted on the ag Software formum direct people to use their sample applications to answer their questions. However, unless I am misunderstanding something, many of their sample applications appear to be out of date or not suitable for my needs. The following code is an example of my attempting to use their libraries to create a Group chat. If anyone has used their library perhaps they can point out what I am doing wrong.

These are my using directives

using System;
using Matrix.Xmpp.Disco;
using Matrix.Xmpp.Client;
using Matrix.Xmpp.Session;
using Matrix.Xmpp;
using Matrix;

Here is the code that connect to the Xmpp Client

readonly XmppClient _xmppClient = new XmppClient();

public string Connect() {
   try
   {
       _xmppClient.SetUsername(OPENFIRE_USER_NAME);
       _xmppClient.Password = OPENFIRE_PASSWORD;
       _xmppClient.SetXmppDomain(OPENFIRE_SERVER);

       _xmppClient.Show = Matrix.Xmpp.Show.chat;
       _xmppClient.AutoRoster = true;
       _xmppClient.Open();

                return "Connection Succesful";
    }
    catch (Exception ex)
    {
       _logger.LogError("SessionManager", "Connect", "Could not connect to Openfire                     Server", ex.ToString());
                        return "Could not Connect to Openfire Server";
    }
}

and this is the code that is suppose to create a new chatroom

public string CreateRoom(string roomName, string serverName, string userName)
{
    Jid groupJid = new Jid(userName, serverName, "gec2o");

    using (MucManager mucManager = new MucManager(_xmppClient))
    {
        mucManager.EnterRoom(groupJid, roomName, true);
        mucManager.RequestInstantRoom(groupJid);
    }

    return "";
}

However no chatroom is created on the server and no exception is thrown. Also I know that I am able to use their library to connect to my server because I can see the my login name appear in openfire's list of users. While they have all their class documented in a file, the library offers little or no comments on what each class/method actually does and how it should be used. Again, there forum mostly tells people to look at sample code which is largely unhelpful and like soapbox this library does not appear to be that well supported (looks like one developer answering ever single question).

I briefly looked into other libraries such as jabber-net but that appeared to be the same story as Soapbox and Matrix in terms of support and documentation.

I also came across IP*Works Internet Toolkit but that library appears to be somewhat cost prohibitive.

I realize that I've made a good deal of assumptions throughout this question but I've been researching for several days now and this is the best conclusions I've been able to come to. I'm hoping someone can either correct my assumptions or recommend a library that does not exhibit these issue I've been facing.

回答1:

Most of XmppClient works asynchronously. When you call someting like client.Open(), it returns immediately but you need to wait for it to raise the OnBind() event before doing anything with the mucManager. For example:

    public class ChatRoom
    {
        private readonly ILogger _logger;
        private XmppClient _client;
        private MucManager _mucManager;

        public ChatRoom(ILogger logger)
        {
            _logger = logger;           
        }

        public string UserName { get; set; }
        public string Password { get; set; }
        public string XmppDomain { get; set; }
        public System.Uri BoshUri { get; set; }
        public string RoomJid { get; set; }
        public string RoomNick { get; set; }

        public void Start()
        {
            _client = new XmppClient(UserName, XmppDomain, Password);               
            _client.OnBind += (o, e) => _CreateChatRoom(_client, RoomJid, RoomNick);
            _client.OnSendXml += (o, e) => Trace(ConsoleColor.DarkGreen, "Sending:\n {0}", e.Text);
            _client.OnReceiveXml += (o, e) => Trace(ConsoleColor.DarkMagenta, "Receiving:\n {0}", e.Text);
            _client.OnError += (o, e) => Trace(ConsoleColor.Red, "Error: {0}", e.Exception);
            _client.Open();
            _client.Close(); 
        }
        private void Trace(ConsoleColor color, string msg, params object[] args)
        {
            var oldColor = _logger.Color;
            _logger.Color = color;
            _logger.Log(msg, args);
            _logger.Color = oldColor;
            Debug.WriteLine(msg, args);
        }

        private void _CreateChatRoom(XmppClient client, string chatRoomName, string roomNick)
        {
            _mucManager = new MucManager(client);
            _mucManager.EnterRoom(chatRoomName, roomNick);            
        }

        public void SendMessage(string text)
        {
            _client.Send(new Message("muc@conference.dgwbhbm1", MessageType.groupchat, text));
        }

        public void End()
        {
            _client.Close();
        }

        public void Invite(Jid[] user)
        {
            _mucManager.Invite(user, RoomJid, "Come chat");
        }      
    }


回答2:

So it looks as though all along that the answer to this question was that my original preferred library, (Soapbox Studio SDK) does in fact support TLS encryption and therefore was by best choice all along. It looks as though TLS is just not well documented and/or I missed this feature.

Depending upon your server configuration ( I am using an Openfire Server ), you should be able to configure your server to only accept encrypted connections. Rather than using the SSL (which Openfire is the process of deprecated from its server ) and attempting to connect over the SSL port 5223, Simply connected over the default port (5222) and requiring an encrypted connection will force the client to send the data using TLS and automatically negotiate the handshake. Also the server can be configured to prevent clients from creating additional users. By controlling which clients are able to create XMPP users on your server rather than issuing SSL certificates you therefore essentially ensure secure communication throughout.



标签: c# ssl xmpp survey