How to implement a single chat client using ionic and strophe?


#1

I’m using Ionic 3 and strophe.js with an eJabberd xmpp server. I connect very well and I can do a ChatRoom. Everything is going well at this level.

Now the problem is that I can not do sigle chat (One to One). I am new to XMPP and this is my first project.

So your help will be welcome and even your examples on how to make a single chat using IONIC 2-3, ANGULAR 4-5 and STROPHE.JS XMPP.

Please help me.

Here is my code for ChatRoom Service:

xmpp-service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Events } from 'ionic-angular';
import { Strophe } from 'strophe.js';
declare let Strophe: any;

export class Message {
    id: String;
    senderId: String;
    text: String;
    time: String;
}

@Injectable()
export class XMPPService {
    private dismissObserver: any;
    public dismiss: any;

    private BOSH_SERVICE: string = "localhost:5280/http-bind/";
    private CONFERENCE_SERVICE: string = "conference.localhost";
    private connection: Strophe.Connection;
    private roomName: string = "";

    constructor(public events: Events) {
        this.dismissObserver = null;
        this.dismiss = Observable.create(observer => {
            this.dismissObserver = observer;
        });
    }

    /*Function
        Connects the client from the Jabber server.
      Parameters:
        (String) jid - Jabber id.
        (String) host - Host name.
        (String) pass - Password.
      Returns:
    */

    login(jid, host, pass) {
        this.connection = new Strophe.Connection(this.BOSH_SERVICE, { 'keepalive': true });
        this.connection.connect(jid + '@' + host, pass, (status) => {
            this.onConnect(status);
        });
    }

    /*Function
        Disconnects the client from the Jabber server.
      Parameters:
      Returns:
    */

    logout() {
        this.connection.options.sync = true; // Switch to using synchronous requests since this is typically called onUnload.
        this.connection.flush();
        this.connection.disconnect();
    }

    /*Function
        Queries a room for a list of occupants
      Parameters:
      Returns:
        iq - Room info.
    */

    allRoster() {
        this.connection.muc.init(this.connection);
        return new Promise<any>(resolve => {
            this.connection.muc.queryOccupants(this.CONFERENCE_SERVICE, function (msg) {
                let items = [];
                let rosters = msg.querySelectorAll('item');

                rosters.forEach(function (roster) {
                    items.push({
                        id: roster.getAttribute("jid"),
                        name: roster.getAttribute("name") || roster.getAttribute("jid"),
                        lastText: 'Available to Chat',
                        avata: 'assets/imgs/ben.png'
                    });
                });

                resolve(items);
            }, function (err) {
                console.log("rooms - error: " + err);
                console.log(err);
            })
        });
    }

    /*Function
        Create multi-user chat room.
      Parameters:
        (String) roomName - The multi-user chat room name.
      Returns:
      id - the unique id used to create the chat room.
    */
    create(roomName) {
        let nick = this.getNick();
        let roomId = this.timestamp();
        let roomJid = roomId + "@" + this.CONFERENCE_SERVICE
        let room = roomJid + "/" + nick;
        this.connection.muc.setStatus(roomId + "@" + this.CONFERENCE_SERVICE, nick, null, null);
        this.connection.muc.createInstantRoom(room, roomName,
            function (status) {
                console.log("Succesfully created ChatRoom", status);
            }, function (err) {
                console.log("Error creating ChatRoom", status);
                console.log(err);
            });

        this.connection.muc.setRoomName(roomId + "@" + this.CONFERENCE_SERVICE, nick);
        this.setRoomName(roomName);

        return roomJid;

    }

    /*Function
        Join a multi-user chat room
      Parameters:
        (String) roomJid - The multi-user chat room to join.
      Returns:
    */
    join(roomJid) {
        this.connection.muc.join(roomJid, this.getNick(), null, null, null, null, null, null);
    }

    /*Function
        Send the message in the chat room.
      Parameters:
        (String) roomJid - The multi-user chat room id.
        (String) message - Send message.
      Returns:
    */

    sendMessage(roomJid, message) {
        this.connection.muc.groupchat(roomJid, message, null);
    }

    /*Function
        Send a mediated invitation.
      Parameters:
        (String) roomJid - The multi-user chat room name.
        (String) id - The invitation's receiver.
      Returns:
    */

    invite(roomJid, id) {
        if (id !== "") {
            this.connection.muc.invite(roomJid, id, "hi?");
        }
    }

    // Create timestamp for multi-user chat room id.
    timestamp() {
        return Math.floor(new Date().getTime() / 1000);
    }

    // Set room name.
    setRoomName(roomName) {
        this.roomName = roomName;
    }

    // Get room Name
    getRoomName() {
        return this.roomName;
    }

    // Parse nickname of jabber id.
    getNick() {
        let nick = this.connection.jid;
        nick = nick.substring(0, nick.indexOf('@'));
        return nick;
    }

    onRegister(status) {
        if (status === Strophe.Status.REGISTER) {
            // fill out the fields
            this.connection.register.fields.username = "juliet";
            this.connection.register.fields.password = "R0m30";
            // calling submit will continue the registration process
            this.connection.register.submit();
        } else if (status === Strophe.Status.REGISTERED) {
            console.log("registered!");
            // calling login will authenticate the registered JID.
            this.connection.authenticate();
        } else if (status === Strophe.Status.CONFLICT) {
            console.log("Contact already existed!");
        } else if (status === Strophe.Status.NOTACCEPTABLE) {
            console.log("Registration form not properly filled out.")
        } else if (status === Strophe.Status.REGIFAIL) {
            console.log("The Server does not support In-Band Registration")
        } else if (status === Strophe.Status.CONNECTED) {
            // do something after successful authentication
        } else {
            // Do other stuff
        }
    };

    /*Function
        Connect XMPP.
      Parameters:    
      Returns:
        status - Status of connection.
    */
    onConnect(status) {
        var self = this;

        switch (status) {
            case Strophe.Status.CONNECTED:
                console.log('[Connection] Strophe is Connected');

                this.connection.addHandler((msg) => { self.onMessage(msg); return true; }, null, 'message', null, null, null);
                this.connection.addHandler((stanza) => { self.onSubscriptionRequest(stanza) }, null, "presence", "subscribe");

                this.dismissObserver.next("login");

                break;
            case Strophe.Status.ATTACHED:
                console.log('[Connection] Strophe is Attached');
                break;

            case Strophe.Status.DISCONNECTED:
                console.log('[Connection] Strophe is Disconnected');
                this.dismissObserver.next("logout");
                break;

            case Strophe.Status.AUTHFAIL:
                console.log('[Connection] Strophe is Authentication failed');
                break;

            case Strophe.Status.CONNECTING:
                console.log('[Connection] Strophe is Connecting');
                break;

            case Strophe.Status.DISCONNECTING:
                console.log('[Connection] Strophe is Disconnecting');
                break;

            case Strophe.Status.AUTHENTICATING:
                console.log('[Connection] Strophe is Authenticating');
                break;

            case Strophe.Status.ERROR:
            case Strophe.Status.CONNFAIL:
                console.log('[Connection] Failed (' + status + ')');
                break;

            default:
                console.log('[Connection] Unknown status received:', status);
                break;
        }
    };

    // Parse multi-chat room id.
    getParseRoomJid(id) {
        var pos = id.indexOf('/');

        if (pos > 0) {
            id = id.substring(0, pos);
        }

        return id;
    }

    // parse jabber id.
    getParseID(id) {
        var pos = id.indexOf('/');

        if (pos > 0) {
            id = id.substring(pos + 1, id.length);
        }

        return id;
    }

    //When a new message is recieved
    onMessage(msg) {
        let message: Message;
        let from = msg.getAttribute('from');
        let type = msg.getAttribute('type');
        let elems = msg.getElementsByTagName('body');
        var delays = msg.getElementsByTagName('delay');
        if (type == "groupchat" && elems.length > 0) {
            let body = elems[0];
            let textMsg = Strophe.getText(body);
            //let currentDate: Date;
            let currentDate = new Date();
            let date = currentDate.toLocaleTimeString().replace(/:\d+ /, ' ');

            // history
            if (delays.length > 0) {
                let delay = delays[0];
                date = delay.getAttribute('stamp');
            }

            message = {
                id: this.getParseRoomJid(from),
                senderId: this.getParseID(from),
                text: textMsg,
                time: date
            };
            console.log('MSG>>', message)
            this.events.publish('message', message);
        }
    };

    onSubscriptionRequest(stanza) {
        console.log(stanza);
    }
}

I need to implement a sigle chat, please help me.


#2

I’m also developing an ionic xmpp messaging app and I’m using the strophe library, and I’m having some difficulties. Let’s exchange contacts to share experiences … I can send my code to you without any problem … I’m looking for someone who can exchange experience with me in this environment XMPP / ionic3 / angular


#3

hey i’m also facing same problem using xmpp-ionic3-master github sample but i didn’t get idea about how to send message to single user. please help tanks