Сообщения узла xmpp не отправляются в правильное место назначения

Я использую сервер node-xmpp в качестве сервера чата для 2 клиентов: Psi и Spark. Я регистрирую учетную запись для каждого клиента. Я хочу отправить из учетной записи Psi сообщение в учетную запись Spark. Каждый раз, когда я отправляю сообщение из Учетная запись той же учетной записи получает сообщение. Я хочу добавить друга в свой список (я не знаю, почему это не работает. Возможно, это не реализовано) и правильно отправлять сообщения. Я использую узел xmpp server/examples/ server-and-client.js. Спасибо за советы.


person Worker1    schedule 21.08.2015    source источник


Ответы (2)


Этот полный код работает очень хорошо для меня:

var xmpp = require('node-xmpp-server');

function generateRoster(jid, name, id, to) {
    // This is a roster request, we create the response node
    var roster = new xmpp.Element('iq', {
        id: id,
        to: to,
        type: 'set'
    });

    roster.c('query', {xmlns: 'jabber:iq:roster', ver: 'ver13'})// We add a children tag `query`, with the two attribute xmlns and ver
        .c('item', { // We add a children 'Item'
            jid: jid, // We send the jid and the name
            name: name,
            subscription: 'both'
        }).c('group').t('Connected Clients'); // We add it to the 'Connected Clients' group

    return roster;
}

var startServer = function (done) {
    // Sets up the server.
    server = new xmpp.C2S.TCPServer({
        port: 5222,
        domain: 'localhost'
    });

    var connectedUsers = [];
    var clientsHandles = {};

    // On connection event. When a client connects.
    server.on('connection', function (client) {
        var userJid = null;
        // That's the way you add mods to a given server.

        // Allows the developer to register the jid against anything they want
        client.on('register', function (opts, cb) {
            console.log('REGISTER');
            console.log(cb);
            cb(false)
        });

        // Allows the developer to authenticate users against anything they want.
        client.on('authenticate', function (opts, cb) {
            //console.log('server:', opts.username, opts.password, 'AUTHENTICATING')
            if (opts.password === 'secret') {
                //console.log('server:', opts.username, 'AUTH OK')
                cb(null, opts)
            }
            else {
                //console.log('server:', opts.username, 'AUTH FAIL')
                cb(false)
            }
        });

        client.on('online', function () {
            userJid = client.jid.user + '@' + client.jid.domain + '/' + client.jid.resource;
            console.log(userJid + 'ONLINE');

            for (var i = 0; i < connectedUsers.length; i++) {
                var myRoster = generateRoster(userJid, userJid, 'myRandomId', connectedUsers[i]);

                if (clientsHandles[connectedUsers[i]]) {
                    clientsHandles[connectedUsers[i]].send(myRoster);
                    console.log("Sending my new infos to ", connectedUsers[i]);
                }
            }

            connectedUsers.push(userJid);
            client.jid.userJid = userJid;
            clientsHandles[userJid] = client;
        });

        // Stanza handling
        client.on('stanza', function (stanza) {
            if (stanza.is('message') && (stanza.attrs.type !== 'error')) {
                if (clientsHandles[stanza.attrs.to]) {
                    clientsHandles[stanza.attrs.to].send(stanza);
                }
            }
            else if (stanza.is('presence')) {
                // We loop through the user list
                for (var j = 0; j < connectedUsers.length; j++) {
                    console.log(stanza.toString());
                    var jid = connectedUsers[j];
                    stanza.to = jid;
                    clientsHandles[jid].send(stanza);
                }
            }
            else if (stanza.is('iq') && stanza.attrs.type == 'get') {
                for (var i = 0; i < stanza.children.length; i++) {
                    if (stanza.children[i].name == 'query' && stanza.children[i].attrs.xmlns == 'jabber:iq:roster') {

                        // We loop through the user list
                        for (var j = 0; j < connectedUsers.length; j++) {

                            var roster = generateRoster(connectedUsers[j], connectedUsers[j], stanza.attrs.id, stanza.attrs.from);
                            client.send(roster); // We send it back to the client
                        }

                    }
                }
                client.send(stanza);
            }
            else {
                client.send(stanza);
            }
        });

        // On Disconnect event. When a client disconnects
        client.on('disconnect', function () {
            if (userJid) {
                console.log(userJid, "DISCONNECTED");
                connectedUsers.splice(connectedUsers.indexOf(userJid), 1);
                delete clientsHandles[userJid];
            }
        });

    });

    server.on('listening', done)
};

startServer(function () {
    console.log("Server running");
});

Когда приходит строфа сообщения, я проверяю, подключен ли получатель или нет, и если да, то отправляю ему строфу.

person Alekos Filini    schedule 25.08.2015
comment
Хорошо .. я попробую и вернусь :) - person Worker1; 25.08.2015
comment
Я подключен к двум экземплярам Spark. Я отправляю сообщение от пользователя 1 пользователю 2. Пользователь 2 не получает сообщение - person Worker1; 25.08.2015
comment
Еще одна вещь здесь.. Пользователи, кажется, не в сети, но они онлайн... Что мне делать в этой ситуации? - person Worker1; 25.08.2015
comment
Что мне делать? Я вижу, ты хорошо знаешь, как работать с xmpp - person Worker1; 25.08.2015
comment
Это работает почти во всех случаях, но это должно быть исправлено. Для поддержки онлайн-функции вам просто нужно транслировать сообщения о присутствии, когда вы их получаете. - person Alekos Filini; 25.08.2015
comment
Во-первых, я хочу поблагодарить вас за вашу помощь ... это было здорово ... я задаю вам еще один вопрос ... Моя цель - создать приложение для чата. Как клиент, что я должен использовать (мне нужно что-то для Angular JS)? - person Worker1; 26.08.2015
comment
Вы можете использовать библиотеку node-xmpp-client, которая должна работать и в браузере. - person Alekos Filini; 26.08.2015
comment
Да, нет проблем. Может быть, было бы лучше открыть новый вопрос, а затем связать его здесь и отметить меня - person Alekos Filini; 26.08.2015
comment
ХОРОШО! Я сделаю это :) - person Worker1; 26.08.2015
comment
вы можете подключиться с node-xmpp-client к серверу, который вы публикуете здесь? - person Worker1; 26.08.2015
comment
Вот ссылка на вопрос @Alekos Filini: stackoverflow.com/q/32221452/5247401 - person Worker1; 26.08.2015

Отправьте сообщение с правильным клиентским подключением, т. е.

1). Сохраните все подключения клиентов в массиве во время аутентификации.
2). Когда приходит сообщение, найдите правильного клиента, связанного с полем «Кому» в разделе сообщения.
var ReceiverCleint = getClient(msgStanza.attrs.to)
3). вернуть правильный клиент и отправить сообщение через него.
ReceiverCleint.send(msgStanza)

Я также работаю над той же демонстрацией, меня беспокоит только то, что когда добавляется больше пользователей, это будет проблемой, поскольку ему приходится повторять каждое сообщение через всех клиентов.

Любой лучший подход приветствуется.

Код:

var clients = new Array();

c2sRouter.on("connection", function(client){

client.on("register", function(opts, cb){
    console.log("client server", "register");
})

client.on("authenticate", function(opts, cb){
    console.log("client server", "authenticate");

    if(opts.password === "tushar" || opts.password === "tushar1"){
        clients.push(client);
        cb(null, opts);
    }else{
        cb(false, opts);
    }
})

client.on("online", function(){
    console.log("client server", "online");

})

client.on("stanza", function(stanza){
    console.log("client server", stanza.toString());

    if(stanza.is("message")){
        var receiverClient = getClient(stanza.attrs.to)
        if(receiverClient === undefined){
            client.send(stanza);
        } else {
            receiverClient.send(stanza);
        }
    }
})

client.on("disconnect", function(){
    console.log("client server", "disconnect");

})
})

var getClient = function (to) {
var clientLength = clients.length;
var client
var clientId;
for(var i = 0; i < clientLength; i++){
    client = clients[i];
    clientId = client.jid.user + "@" + client.jid.domain
    if(to.indexOf(clientId) == 0){
        return client;
    }
}
}
person user1361425    schedule 23.08.2015
comment
У вас есть код или пример? Я немного запутался :( - person Worker1; 24.08.2015
comment
Вы использовали этот код с клиентом Spark? Попробуйте подключиться к серверу с двумя экземплярами Spark. Проверьте, работает ли он. Чтобы общаться в этих экземплярах - person Worker1; 25.08.2015