Closed akoepe closed 7 years ago
If you can find the S22.XMPP (of which the Sharp code originated) source, there is a help file that contains some helpful examples. Here is what the help file has on account registration that I used as an example to get my code up and running:
Create an instance of the XmppClient class using the constructor that does not expect username and password parameters, connect to the XMPP server on which you wish to register a new XMPP account and call the Register method, passing it a delegate of type RegistrationCallback.
using (XmppClient client = new XmppClient("jabber.ccc.de")) {
// Setup any event handlers here, before connecting to the server.
// In this example, we don't need to install any.
client.Connect();
// Try to initiate the in-band registration process with the server.
client.Register(RegistrationCallback);
[...]
The RegistrationCallback is a method that is invoked during the registration process to let the user enter any data that the server requires in order to create a new account. Many servers merely require the user to enter their designated username and password, but some ask the user to provide additional information such as his or her real name or ask the the user to enter a CAPTCHA.
To facilitate the different needs of server administrators, XMPP employs a flexible request/submit mechanism similar to HTML forms: The server sends a form with various fields and asks the client to fill it out. What kind of fields the form contains is entirely up to the server administrator and differs from server to server.
A shortended version of the RegistrationCallback method is given below.
static SubmitForm RegistrationCallback(RequestForm form) {
// The RequestForm contains all fields the user is required to fill out
// in order to complete account registration with the XMPP server.
if(!String.IsNullOrEmpty(form.Instructions))
Console.WriteLine(form.Instructions);
SubmitForm submitForm = new SubmitForm();
// Go through each field of the form and gather the data from the user.
foreach (var field in form.Fields) {
// Gather the input data; XMPP dataforms support different field-types
// allowing server administrators to flexibly gather whatever data
// is required to register an account;
DataField f = null;
// The field is a text-field, similar to a WinForms TextControl or HTML input field.
if (field is TextField)
f = ReadTextField(field as TextField);
// The field is a password field, similar to an HTML input field of type "password".
else if (field is PasswordField)
f = ReadPasswordField(field as PasswordField);
// The field is a boolean field, which can be either true or false.
else if (field is BooleanField)
f = ReadBoolField(field as BooleanField);
// The field is an input field expecting a Jabber ID (JID).
else if (field is JidField)
f = ReadJidField(field as JidField);
// Hidden fields should just be returned to the server, usually without
// modification. They serve the same purpose as hidden fields in HTML
// forms.
else if (field is HiddenField)
f = field;
else if (field is FixedField) {
// Fixed fields are static labels of text that should be rendered to the user much
// like a WinForms Label. They don't require any input.
var fixedField = field as FixedField;
Console.WriteLine("Static label: " + fixedField.Description);
}
if (f != null)
submitForm.Fields.Add(f);
}
// Return the filled-out form to the server.
return submitForm;
}
After your callback finishes, you then do an Authenticate to complete the client initialization. Hope this helps.
Forgot to add:
private TextField ReadTextField (DataField textField) {
switch (textField.Name) {
case "email":
return new TextField (textField.Name, textField.Required, textField.Label, textField.Description, _emailAddress);
case "name":
return new TextField (textField.Name, textField.Required, textField.Label, textField.Description, _fullName);
case "password":
return new TextField (textField.Name, textField.Required, textField.Label, textField.Description, _password);
case "username":
return new TextField (textField.Name, textField.Required, textField.Label, textField.Description, _username);
}
return null;
}
Thanks for your answer. I've also found these tutorials, but it was this actually, which I didn't understand.
What exactly should I pass as registrationcallback parameter? Is this a template receveid from the server(in this case how do I get it in my client app and how do I link it into the Register funtion) or is it a template which I add to my client side project, like an xml file or is it a formula, which is already filled out with the user credentials?
I don't need anything fancy just add a user(usrname, password), if my code with some modification from the first message runs in a ConsoleApplication I can figure out the rest.
Thanks again!
The callback takes the RequestForm parameter like shown above. This object is defined in the extension XEP-0004/Dataforms folder. If you take the code from above and paste it verbatim into your class, it will do everything you need. The request form is passed into the client by the xmpp server so you don't have to do anything special other than process all of the data fields and answer, at a minimum, the required fields which are usually just the username/password.
Here is a complete example (this works for other situation where the registration callback is used such as MUC configuration):
internal class Program {
private const string Hostname = "YOUR_XMPP_SERVER_NAME";
private const string Password = "PW";
private const string Username = "UN";
private static void Main () {
using (var client = new XmppClient (Hostname)) {
client.Connect ();
try {
client.Register (RegisterCallback);
client.Authenticate (Username, Password);
} catch (Exception ex) {
Console.WriteLine (ex);
Console.ReadLine ();
}
while (true) {
Console.Write ("> ");
var command = Console.ReadLine ();
if (command == "quit") {
return;
}
}
}
}
private static SubmitForm RegisterCallback (RequestForm form) {
var submitForm = new SubmitForm ();
// Go through each field of the form and gather the data from the user.
foreach (var field in form.Fields) {
// Gather the input data; XMPP dataforms support different field-types
// allowing server administrators to flexibly gather whatever data
// is required to register an account;
DataField f = null;
// The field is a text-field, similar to a WinForms TextControl or HTML input field.
if (field is TextField) {
f = ReadTextField (field as TextField);
} else if (field is ListField) {
f = ReadListField (field as ListField);
} else if (field is ListMultiField) {
f = ReadListMultiField (field as ListMultiField);
} else if (field is BooleanField) {
f = ReadBooleanField (field as BooleanField);
} else if (field is PasswordField) {
f = ReadPasswordField (field as PasswordField);
}
if (f != null) {
submitForm.Fields.Add (f);
}
}
// Return the filled-out form to the server.
return submitForm;
}
private static TextField ReadTextField (DataField field) {
switch (field.Name) {
case "email":
return new TextField (field.Name, Email);
case "name":
return new TextField (field.Name, Name);
case "password":
return new TextField (field.Name, Password);
case "username":
return new TextField (field.Name, Username);
case "muc#roomconfig_roomdesc":
return new TextField (field.Name, "Testing");
case "muc#roomconfig_roomname":
return new TextField (field.Name, "Testing");
}
return null;
}
private static ListField ReadListField (DataField field) {
if (field.Name == "allow_private_messages_from_visitors") {
return new ListField (field.Name, "anyone");
}
if (field.Name == "muc#roomconfig_maxusers") {
return new ListField (field.Name, "200");
}
return null;
}
private static ListMultiField ReadListMultiField (DataField field) {
return field.Name == "muc#roomconfig_presencebroadcast"
? new ListMultiField (field.Name, "moderator", "participant")
: null;
}
private static BooleanField ReadBooleanField (DataField field) {
switch (field.Name) {
case "allow_private_messages":
return new BooleanField (field.Name, true);
case "allow_query_users":
return new BooleanField (field.Name, true);
case "allow_subscription":
return new BooleanField (field.Name, true);
case "allow_visitor_nickchange":
return new BooleanField (field.Name, true);
case "allow_visitor_status":
return new BooleanField (field.Name, true);
case "allow_voice_requests":
return new BooleanField (field.Name, true);
case "mam":
return new BooleanField (field.Name, true);
case "members_by_default":
return new BooleanField (field.Name, true);
case "muc#roomconfig_allowinvites":
return new BooleanField (field.Name, true);
case "muc#roomconfig_changesubject":
return new BooleanField (field.Name, true);
case "muc#roomconfig_membersonly":
return new BooleanField (field.Name, true);
case "muc#roomconfig_moderatedroom":
return new BooleanField (field.Name, false);
case "muc#roomconfig_passwordprotectedroom":
return new BooleanField (field.Name, false);
case "muc#roomconfig_persistentroom":
return new BooleanField (field.Name, true);
case "muc#roomconfig_publicroom":
return new BooleanField (field.Name, true);
case "muc#roomconfig_whois":
return new BooleanField (field.Name, true);
case "public_list":
return new BooleanField (field.Name, true);
}
return null;
}
private static PasswordField ReadPasswordField (DataField field) {
return field.Name == "password"
? new PasswordField (field.Name, Password)
: null;
}
}
OK. Now I understand it, I was confused and thought RegistrationCallback is an object and tried to create it.
Anyway thanks a lot, I really appreciate your help and effort.
Hy! Can somebody help me out, because I can't figure out the built in registration function. How should I create the registrationcallback? A detaild example would also help, I coulnd't find enough information about these functons.
XmppClient client = new XmppClient("hostname"); client.Message += (s, e) => { Console.WriteLine(e.Message); }; client.Register(registrationcallback); client.Connect();
Thanks!