【问题标题】:Append in real time based on values in array根据数组中的值实时追加
【发布时间】:2016-01-06 05:24:25
【问题描述】:

所以,我目前正在附加到我的网页,或者根据存储在数组中的值从中删除。

但是为了让它们出现,我需要重新加载页面,但我需要在不重新加载页面的情况下即时进行。因此,我一追加就可以看到它,当我删除它时也是如此。

我一直在使用 socket.io 服务器端代码来尝试这样做,但结果好坏参半。我对 socket.io 没有太多经验,但仍在努力掌握它。

我实际上只是试图通过将数据附加到表中来实时根据数组 chanArr 中存储的内容发出数据。

app.js 文件

这是我的 socket.io 的服务器端代码,函数 updateSip 将数据发送回客户端。

var ari = require('ari-client');
var util = require('util');
var chanArr = [];
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);

//ARI client
ari.connect('http://localhost:8088', 'asterisk', 'asterisk', clientLoaded);

function clientLoaded(err, client) {
    if (err) {
        throw err;
    }
    // find or create a holding bridges
    var bridge = null;
    client.bridges.list(function (err, bridges) {
        if (err) {
            throw err;
        }

        bridge = bridges.filter(function (candidate) {
                return candidate.bridge_type === 'mixing';
            })[0];

        if (bridge) {
            console.log(util.format('Using bridge %s', bridge.id));
        } else

            client.bridges.create({
                type : 'mixing'
            }, function (err, newBridge) {
                if (err) {
                    throw err;
                }

                bridge = newBridge;
                console.log(util.format('Created bridge %s', bridge.id));
            });
    }
    });

    // handler for StasisStart event
    function stasisStart(event, channel) {
        console.log(util.format(
                'Channel %s just entered our application, adding it to bridge %s',
                channel.name,
                bridge.id));

        channel.answer(function (err) {
            if (err) {
                throw err;
            }

            bridge.addChannel({
                channel : channel.id
            }, function (err) {
                var id = chanArr.push(channel.name)
                    updateSip();
                console.log("User: " + channel.name);
                if (err) {
                    throw err;
                }

                //If else statement to start music for first user entering channel, music will stop once more than 1 enters the channel.
                if (chanArr.length <= 1) {
                    bridge.startMoh(function (err) {
                        if (err) {
                            throw err;
                        }
                    });
                } else {
                    bridge.stopMoh(function (err) {
                        if (err) {
                            throw err;
                        }
                    });
                }

            });
        });
    }

    // handler for StasisEnd event
    function stasisEnd(event, channel) {
        console.log(util.format(
                'Channel %s just left our application', channel.name));
        console.log(channel.name);

        var index = chanArr.indexOf(channel.name);
        chanArr.splice(index, 1);
        updateSip();
    }
    client.on('StasisStart', stasisStart);
    client.on('StasisEnd', stasisEnd);
    client.start('bridge-hold');
    }

    //Socket.io logic here
    server.listen(3009, function () {
        console.log('listening on *:3009');
    });

    app.use(express.static(__dirname + '/public'));
    app.get('/', function (req, res) {
        res.sendfile(__dirname + "/testPage.html");
    });

    io.sockets.on('connection', function () {
        updateSip();
    });

    io.sockets.on('updateSip', function () {
        console.log('Being called!')
        updateSip();
    });

    function updateSip() {
        io.sockets.emit('sip', chanArr);
    }

test.js

客户端 JQuery 和 socket.io 代码以及将元素附加到网页的位置。

jQuery(function ($) {
    var socket = io.connect();
    var $sip = $('#sip');
    socket.on('sip', function (data) {
        var sip = '';
        for (i = 0; i < data.length; i++) {
            sip += data[i]
        if(sip){
        $sip.append('<tr>\
                                    <td>' + sip + '</td>\
                                    <td><input type="checkbox" data-on="Voice" data-off="Muted" checked data-toggle="toggle" data-onstyle="success" data-offstyle="danger"></td>\
                                    <td><button class="btn btn-default kick" id="kick" data-toggle="modal" data-target="#myModal" type="submit">Kick</button></td>\
                                    </tr>');
        }
        else{
            $sip.append('Currently no extensions');
        }
        sip = '';
        }

    });
});

testPage.html

我也在附加。

            <div class="secondary-bridge">
<h3 class="conf-head">Conference call:</h3>
<table class="table table-bordered">
    <thead>
        <tr>
            <th>Extension</th>
            <th>Mute</th>
            <th>Kick</th>
        </tr>
    </thead>
    <tbody id ="sip">
    </tbody>
</table>

编辑: 所以此刻,我必须刷新页面,以便页面运行 updateSip 函数,然后发出并显示已附加的新值,每次我添加或从数组中删除处理要显示的内容的值时我必须刷新页面。

页面加载 -> Array[]-> 调用,在数组中插入值-> Array['SIP-448']-> 重新加载页面 -> 现在可以看到它附加了。

我正在努力让它工作,所以我永远不必刷新。

在征求一些建议之前我尝试的第一件事是建议的方法@show-me-the-code,然后发生了以下情况,它确实做了我想做的事情,但是在 1 个值之后,它会中断,并且值它们从数组中移除后仍然显示在网页上:

1 个值

超过 1 个值

当我刷新页面时,它会转到:

当我尝试从数组中删除一个值时,它会附加上一个值,一旦我刷新页面,只有一个值应该保留。

这是我的大问题,我不知道为什么它现在的行为方式。

【问题讨论】:

  • 我认为在这种情况下你必须检查 WEBSOCKETS
  • 我不能简单地将数据从 Socket.io 服务器端发送到客户端吗?考虑将其用于实时 Web 应用程序?
  • 那么唯一的选择就是继续从服务器轮询以检查后端和前端匹配的对象状态..
  • 我建议用 Javascript 编写 WEBSOCKETS。不是socket.io
  • @AkshayKhandelwal OP 正在使用 websockets,这就是 socket.io 库的用途。乍一看,代码看起来不错,应该可以工作。您是否在开发者控制台和/或节点中遇到任何错误?

标签: javascript jquery node.js socket.io


【解决方案1】:

如果我理解正确,您希望将服务器的数据更新到客户端。

您的代码的问题是您只在客户端连接上调用函数updateSip()。如果你想在其他时候更新它,你必须向你的app.js提供更多代码

例如,您可以创建一个事件侦听器,例如

io.sockets.on('updateSip', function () {
  updateSip();
});

在您的客户端,您可能会创建一个类似的函数

function updateSip() {
    socket.emit('updateSip');  
},

这样,如果您在 test.js 中调用函数 updateSip(),您的服务器就会回答您需要的信息

【讨论】:

  • 是的,你几乎把它钉在了头上,并且知道它只会在连接时被调用,作为 socket.io 的新手,它仍然是一个学习过程。我尝试了类似你所建议的东西,但我不认为正在调用函数或其他东西,结果保持不变。我还尝试在 addChannel 段调用 updateSip 函数,但它确实有效,也无效。原因可以参考上面的评论
  • 因为io.sockets.on('connect',.. 可能在ari.connect 之前触发,可能是您的chanArr 不是最新的。像@show-me-the-code 建议的那样尝试
  • 如果您检查我更新的问题,我已经尝试过该方法并且发生的结果在那里。
  • 代码的格式看起来很糟糕。这样就很难对它有一个很好的了解。好吧,您似乎忘记为您的代码提供函数stasisEnd。我猜你希望var index = chanArr.indexOf(channel.name); chanArr.splice(index, 1);stasisEnd-function 中
  • 我试图减少要查看的代码量,它被包裹在停滞端。我会用该文件的完整代码更新问题。
【解决方案2】:

这就是我要做的。在您的chanArr 更改(添加或删除元素)的服务器端,触发emit('sip', chanArr) 调用。

// right after adding channel to the array
chanArr.push(channel.name);
updateSip();

// also after removing it from the array if it is in different function
chanArr.splice(index, 1);
updateSip();

【讨论】:

  • 我在提出解决方案时做的第一件事就是这样,但它适用于数组中的第一个值,当添加第二个时,它会添加它,但也会添加前一个值,并且如果它们已从数组中删除,则不删除这些值。
  • 当然,因为您每次都发送整个数组。为什么不在添加或删除值时发送值 (channel.name),然后相应地从客户端追加或删除?这将确保您一次只追加或删除一行。
猜你喜欢
  • 1970-01-01
  • 2016-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-09
  • 2016-03-26
  • 1970-01-01
相关资源
最近更新 更多