无法显示从 websocket 到 dataTable 的数据流

Not able to display data streaming from websocket to dataTable

我正在尝试通过 websocket 传输数据并将其显示在数据表中。我能够在我的客户端中获取数据,但 table.

中实际上没有显示任何数据

如何显示更新后的数据 一旦流式传输 websocket 数据,就在数据表中实时放置。

    <script type="text/javascript" charset="utf-8">
        streamData = ""
        streamDataArr = new Array();
            $(document).ready(function() {
                namespace = 'http://localhost:8080/';
                var socket = io(namespace);
                socket.on('connect', function() {
                    socket.emit('my_event', {data: 'connected to the SocketServer...'});
                });
                socket.on('my_response', function(msg, cb) {
                    streamData = JSON.parse(msg.data);
                    $('#log').append('<br>' + $('<div/>').text('logs message :- ' + JSON.stringify(streamData)).html());
                    streamDataArr.push([streamData.instrument_token, streamData.last_price, streamData.ohlc.open])
                    console.log(streamDataArr); //value is present
                });         
            });
    
        $(document).ready(function() 
        {
            alert("Arr:- ",streamDataArr) //empty why ?
            alert("soemthing", streamDataArr[0]) //empty why ?
            var table = $('#example').DataTable(
                {
            data: streamDataArr,
            columns: [
                { title: "Name" },
                { title: "last price" },
                { title: "Open price" },
                    ]
                } 
                                               );
        });
        </script>

<body>
    <table id="example" class="display" style="width:100%"> </table>   
</body>

P.S。我是 datatable 和 socket-io

的新手

编辑:- 代码的 v2。

 <script type="text/javascript" charset="utf-8">
    streamData = ""
    streamDataArr = new Array();
       

    
    function fillDataTable(dataSet){
    {
        if (document.readyState === "complete"){
        //alert("Arr:- ",dataSet) //empty why ?
        //alert("soemthing", dataSet[0]) //empty why ?
        var table = $('#example').DataTable(
            {
        data: dataSet,
        retrieve: true,
        deferRender: true,
        searching: false,
        paging: false,
        columns: [
            { title: "stock Name" },
            { title: "stock last price" },
            { title: "stock Open price" },
                ]
            });
    
            }
        }
    }

            namespace = 'http://localhost:8080/';
            var socket = io(namespace);

            socket.on('my_response', function(msg, cb) {
                streamData = JSON.parse(msg.data);
                $('#log').append('<br>' + $('<div/>').text('logs message :- ' + JSON.stringify(streamData)).html());
                streamDataArr.push([streamData.instrument_token, streamData.last_price, streamData.ohlc.open])
                console.log(streamDataArr); //value is present
                fillDataTable(streamDataArr);
                
                $('#example').DataTable().row.add( [streamData.instrument_token, streamData.last_price, streamData.ohlc.open] ).draw();
                redraw();
                // $('#example').DataTable().row(streamData.instrument_token).data("stock last price")  =  streamData.last_price
                // $('#example').DataTable().row(streamData.instrument_token).data("stock Open price")  =  streamData.ohlc.open
                
            });     
            function redraw(){  
                var table = $('#example').DataTable();
                var index = table.column( 0 ).data().indexOf( streamData.instrument_token );
                if (index != ""){
                alert("index is", String(index))
                console.log(String(index))
                $('#example').DataTable().row(index).data( [streamData.instrument_token, streamData.last_price, streamData.ohlc.open] ).draw();
                }
            }
    </script>

因此 1 条目出现了两次,我无法真正测试它是否在源 websocket 关闭时就地更新

v3 版本。通过这种方式,数据正在流式传输,但我有重复的条目,如图所示。我还注意到它正在用其他股票替换条目。

       <script type="text/javascript" charset="utf-8">    
        $(document).ready(function () {
    var table; 
    
    // a dummy initial row for testing:
    var dataSet = [  ];
    $(document).ready(function () {
        table = $('#example').DataTable({
            data: dataSet,
            columns: [
                {title: "Symbol", data: "instrument_token"},
                {title: "StockName", data: "stockName"},
                {title: "last_price", data: "last_price"},
                {title: "ohlcOpen", data: "ohlc.open"}
                
            ]
        });
    });
    
    // small helper function for selecting element by id
    let id = id => document.getElementById(id);
    
    //Establish the WebSocket connection and set up event handlers
    let ws = io.connect(null, {port: 8000, rememberTransport: false});
                ws.on('my_response', function(msg, cb) {
                    updateTable(msg);
                });
    //ws.onmessage = msg => updateTable(msg);
    ws.onclose = () => alert("WebSocket connection closed");
        
    function updateTable(message) {
        let stockData = JSON.parse(message.data);        
        console.log("in updateTable stock data:-", stockData)
        // check if symbol already in table:
        var index = table.column( 0 ).data().indexOf( stockData.instrument_token );
        
        if (index >= 0) {
            // update the existing row:
            table.row( index ).data( stockData ).draw();
        } else {
            // insert a new row:
            table.row.add( stockData ).draw();
        }
    }
    
    });
</script>

我有一个示例 DataTable 从 websocket 源接收数据 - 但它是标准 JavaScript WebSocket 库 - 不是 socket.io.

不过,我认为这不是问题,因为在 Datatable 中显示数据的方法是基于将 DataTables API 与从websocket - 你已经有了这些数据:console.log(streamDataArr); //value is present.

在我的测试示例中,我有一个简单的 table,其中包含一条源自局部变量的初始记录:

var dataSet = [ { "msg": "started" } ];
$(document).ready(function () {
  $('#example').DataTable({
    data: dataSet,
    columns: [{title: "Message", data: "msg"}]
  });
});

我的 websocket 数据在我的例子中提供了简单的字符串(当然,它可以是 JSON 或任何你想要的)。我获取该字符串并使用 DataTables API 将其添加到 DataTable。我在数据可用的套接字处理程序中执行此操作:

var socketOutputText = [the data from the socket];
var newRow = { "msg": socketOutputText  };
$('#example').DataTable().row.add( newRow ).draw();

在这里,我创建了一个 JS 对象 newRow,其中包含一行 DataTable 数据所需的字段。在我的例子中只有一个字段(table 只有 1 列)。我使用 msg 的数据名称来匹配我在 DataTable 中定义的名称。

我使用 DataTables row.add() API 函数将行添加到 table 并强制重新显示 table.

这很粗糙 - 它只是不断向 table 添加新行。

您可以通过添加逻辑来增强这一点,以检查 table 中是否存在记录(例如,查找行键),然后更新现有行。因此,套接字数据可以是股票行情提要,包含代码和价格。

您可以使用 indexOf() API 调用来定位您的股票代码的现有行,然后您可以使用 row().data( newRow ) API 调用来更新现有的table.

中的行

使用这种方法,您需要将所有套接字处理放在“文档就绪”函数中,以确保您的代码不会尝试与尚未初始化的 Datatable 交互。


这是基本网页。我用它来显示 DataTable - 但我 用它来输入我的代码数据(就像测试的方式):

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Webs Sockets</title>

        <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
        <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
        <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

        <link rel="stylesheet" href="style.css">
    </head>
    <body>

        <table id="example" class="display dataTable cell-border" style="width:100%"></table>

        <br><br>

        <div id="tickControls">
            <input id="message" placeholder="Enter data as JSON string">
            <button id="send">Send</button>
        </div>
        
        <div id="tick"></div>
        <script src="websocketDemo.js"></script>


    </body>
</html>

上页中使用的websocketDemo.js


$(document).ready(function () {

    var table; 
    
    // a dummy initial row for testing:
    var dataSet = [ {"symbol": "AAPL", "price": 134.28} ];
    $(document).ready(function () {
        table = $('#example').DataTable({
            data: dataSet,
            columns: [
                {title: "Symbol", data: "symbol"},
                {title: "Price", data: "price"}
            ]
        });
    });

    // small helper function for selecting element by id
    let id = id => document.getElementById(id);

    //Establish the WebSocket connection and set up event handlers
    let ws = new WebSocket("ws://" + location.hostname + ":" + location.port + "/ticker");
    ws.onmessage = msg => updateTable(msg);
    ws.onclose = () => alert("WebSocket connection closed");

    // Add event listeners to button - this is just used to provide test input data
    id("send").addEventListener("click", () => sendAndClear(id("message").value));

    function sendAndClear(message) {
        if (message !== "") {
            ws.send(message);
            id("message").value = "";
        }
    }

    function updateTable(message) {
        let stockData = JSON.parse(message.data);        
        // check if symbol already in table:
        var index = table.column( 0 ).data().indexOf( stockData.symbol );
        
        if (index >= 0) {
            // update the existing row:
            table.row( index ).data( stockData ).draw();
        } else {
            // insert a new row:
            table.row.add( stockData ).draw();
        }

    }

});

再次记住,这处理输入测试数据,以及更新数据表。代码中包含注释。

页面如下所示:

要输入新的股票价格,我在输入字段中输入了一段 JSON。在上面的屏幕截图中,您可以看到输入这两个单独的代码更新的结果:

{"symbol": "MSFT", "price": 258.82}

{"symbol": "AAPL", "price": 133.97}

您提到您一次处理多个符号 - 所以我的基本演示必须遍历 JSON 以在我的 updateTable() 函数中分别处理每个符号。