Geeks With Blogs

Lance's TextBox
Adding multi-user chat to my jabber app The XMPP component provides extensibility by providing the developer with the capability of sending custom commands as well as overseeing all incoming messages so that you can add custom handlers for them. For example, there is a jabber extension proposal to provide a means for multi-user chat capabilities. Multi-user chat for Jabber is defined in JEP-0045.

To add chat capabilities to my own jabber client is fairly simple and straight-forward. First, I added functions to send custom commands to the server for joining and leaving chat rooms:

    Private Sub JoinRoom(ByVal groupname As String, ByVal conference As String)
Try Xmpps1.SendCommand("<PRESENCE to='" + groupname + "@" + conference + "/" + Xmpps1.User + "' from='" + Xmpps1.User + "@" + Xmpps1.Config("Domain") + "' />")
Catch ex1 As Exception
End Try End Sub Private Sub LeaveRoom(ByVal roomname As String, ByVal conference As String)
Try Xmpps1.SendCommand("<PRESENCE to='" + roomname + "@" + conference + "/" + Xmpps1.User + "' from='" + Xmpps1.User + "@" + Xmpps1.Config("Domain") + "' type="unavailable" />")
Catch ex1 As Exception
End Try End Sub

And another for sending an invitation request to a room (In the JEP, invitations are sent through the room itself so that the server can administer access rights and such):

    Private Sub InviteUser(ByVal invitee As String, ByVal roomname As String, ByVal conference As String)
Xmpps1.SendCommand("<MESSAGE to='" + roomname + "@" + conference + "' from='" + Xmpps1.User + "@" + Xmpps1.Config("Domain") + "'><X xmlns=""><INVITE to='" + invitee + "'><REASON>You've been invited to chat!</REASON></INVITE></X></MESSAGE>")
End Sub

At this point I could successfully create/join a chat room, invite a buddy to join the chat room, and leave the chat room. Next issue: sending and receiving messages.

To send a message to the room, I need to do more than just specify the recipient of my message as the room itself. I also need to set the MessageType property of teh XMPP component to be a "GroupChat" message. No big deal. I use the same SendMessage function as before to handle the sending, except I added a parameter to it where I could specify the messagetype.


Now this is the same SendMessage function except for three changes:

  • I now set the XMPP MessageType to the parameter value.
  • If the outgoing message is going to a chat room, I specify the jabberid to send to with group chat service name appended, ie: "chatroomname@conference.server".
  • I dont add the outgoing data to my conversation history textbox if it is a GroupChat message (because the group itself is going to echo what I send to it).

Next issue: All the messages coming from people in the chat room show up in my client as being from the chat room itself, rather than from those buddies. This is because the messages are from the chat room itself. :) However the server does send the nickname of the buddy who initiated the message in the place of the resource. To accomodate for this, I modified my MessageIn event slightly to check to see if the Domain is my conference service. If it is, and a resource is specified, then I know this is a message from a member of the chat room: Dim nick As String = e.From If e.Domain.Equals("conference.testboy") And Not e.Resource.Equals("") Then nick = e.Resource If i > 0 Then 'add the message to an existing chat tab w/o changing focus NewMessage(i, nick, e.MessageText) Else 'create a new chat tab, don't change focus NewMessage(-1, nick, e.MessageText) End If

Thats it, I can now create/join rooms, invite users, and converse back and forth. Now I need to add the ability to accept invitations from other users. To do this I can add code to either the PITrail event or the MessageIn event where I can look for the invite element being sent in the body of the message and act accordingly. If I see this invite element defined in the message coming in, I can look for the from tag to see who has invited me and to what room. Now if I want to accept the invitation I can use the same JoinRoom function that I showed previously:

    Dim prompt As String = inviter + " has invited you to join the chat room """ + roomname + ".  Do you wish to accept?"     If MessageBox.Show(prompt, "Chat Invitation", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) = DialogResult.Yes Then         JoinRoom(roomname, conference)     Else         DeclineInvitation(roomname, conference)     End If
Posted on Thursday, October 27, 2005 2:07 PM Programming | Back to top

Comments on this post: Adding multi-user chat capability to my custom jabber client

# re: Adding multi-user chat capability to my custom jabber client
Requesting Gravatar...
We do get this error often .. What is the workaround?
System.InvalidOperationException was unhandled by user code
Message="Cross-thread operation not valid: Control 'rtbLog' accessed from a thread other than the thread it was created on."
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.RichTextBox.SetCharFormatFont(Boolean selectionOnly, Font value)
at System.Windows.Forms.RichTextBox.set_SelectionFont(Font value)
at IJabber.Form1.AddToConversation(RichTextBox target, String sender, String text) in C:\Documents and Settings\Administrator.ZEALSERVER\Desktop\IJabberSSL\Main.vb:line 732
at IJabber.Form1.Xmpps1_OnPITrail(Object sender, XmppsPITrailEventArgs e) in C:\Documents and Settings\Administrator.ZEALSERVER\Desktop\IJabberSSL\Main.vb:line 612
at nsoftware.IPWorksSSL.Xmpps.nsoftware.core.IXmppEvents.FirePITrail(Int32 direction, ips61s pi)
Left by Pooran on Oct 12, 2006 1:29 AM

# re: Adding multi-user chat capability to my custom jabber client
Requesting Gravatar...
Oops, thats because you're using the old VS 2003 project in VS 2005 (my mistake, I hadn't updated the link to go to the 2005 project). I updated it now, so this wont happen again. : )
Left by Lance on Oct 12, 2006 7:00 AM

Your comment:
 (will show your gravatar)

Copyright © Lance Robinson | Powered by: