【问题标题】:Node xmpp messages are not sent to correct destination节点 xmpp 消息未发送到正确的目的地
【发布时间】:2015-08-21 08:15:58
【问题描述】:

我正在使用 node-xmpp 服务器作为 2 个客户端的聊天服务器:Psi 和 Spark。我为每个客户端注册了一个帐户。我想从 Psi 帐户向 Spark 帐户发送一条消息。每次我发送一个来自同一帐户的消息接收消息。我想将朋友添加到我的列表中(我不知道为什么不起作用..可能没有实现)并正确发送消息。我正在使用节点 xmpp 服务器/examples/server-and-client.js.感谢您的建议。

【问题讨论】:

    标签: javascript node.js node-xmpp


    【解决方案1】:

    这个完整的代码对我来说很好用:

    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");
    });
    

    当消息节到达时,我检查接收者是否已连接,如果是,我将节发送给它。

    【讨论】:

    • 好的..我会尝试,我会回来的:)
    • 我连接了两个 Spark 实例。我正在从 user1 向 user2 发送消息 ..user2 没有收到消息
    • 这里还有一件事..用户似乎离线但他们在线...在这种情况下我该怎么办?
    • 我应该怎么做?我看你很清楚如何使用 xmpp
    • 这几乎适用于所有情况,但应该更正。要支持在线功能,您只需在收到状态消息时广播它们。
    【解决方案2】:

    使用正确的客户端连接发送消息,即

    1)。验证时将客户端的所有连接存储在一个数组中。
    2)。当消息到达时,找到与消息节中的“to”字段相关联的正确客户端。
    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;
        }
    }
    }
    

    【讨论】:

    • 你有一些代码或例子吗?我有点困惑:(
    • 您是否将此代码用于 Spark 客户端?尝试使用两个 Spark 实例连接到服务器..检查它是否工作..在此实例中进行通信
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 2021-03-08
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多