3

私は、WebSocketを介して「リアルタイム」でデータを配信および表示する方法の学習に取り組んできました。このコンテキストでは、リアルタイムとは、データが.03〜1秒ごとにセンサー(画像処理を備えたカメラ)から読み取られていることを意味します。各データポイントは、doubleとしてエンコードされた時間と値(t、v)で構成されます(この場合、時間は常に整数ですが、そうなるとは想定していません)。

サーバー側では、Alchemy Websocketの実装(C#)を使用しています。これは、自分の目的のために理解/変更するのが非常に簡単であることがわかったためです。

ここここにあるWebSocketのと、Alchemyに含まれている例を活用しています。

HighChartsを使用してデータを「リアルタイム」で表示していますが、デバッグ目的でdivに出力することもできます(互いに干渉しないように独立した例です)。

その多くはすでにかなりうまく機能していますが、データの送信が速すぎると明らかに問題が発生します(明確にするために、1秒または2秒ごとにポイントに関するデータを送信すると、グラフが表示されなくなります。問題-錬金術サーバーを「送信」関数と呼ぶほど、問題はより顕著になります)。

データが間違った順序で入力されているように見え、興味深い「マングル」効果が発生します。

マングルされたデータポイント

サーバー側のバッファーに含まれるパケットの順序を調べ始めます(サーバーは、新しいユーザーが接続し、すでに実行されているときに、特定の数の「履歴」ポイントを送信するように指示されます。これにより、次のような顕著な問題が発生します。上に示したもの)とクライアント側はタイムスタンプを見て注文を受け取ります。

このエラーは、ページをリロードするたびに異なる「マングル」データセットが生成されるという点で一貫性がありません。これにより、WebSocketを介した通信に責任があるか、錬金術サーバーに関係していることが疑われます。

必要に応じて完全なコードを添付しますが、今はかなり面倒なので、トラブルシューティングのアイデアをもっと探しています。

これは、TCP上に構築されているため、Webソケットでは予期されない動作であることがわかりました。

見るべきものについての提案/アイデアはありますか?

ありがとう!

編集:ページを更新するたびに、故障しているデータポイントの数を確認するために別のテストを実行しました。番号は次のとおりです。

1 2 3 25 6 5 10 11 96 2 8

非常に一貫性がありません(0になることはありません)。確かに面白い!

この結果は、グラフ作成コンポーネントを除外し、データを格納するためにWebSocketと配列のみを使用して取得されました。

アップデート:

入ってくる順序の分析を開始することにしましたが、同じデータセットを使用して順序が正しくないポイントをランダムに受信しているように見えます。順不同のパケットを考慮に入れる「挿入」機能を実装しました。結果(および少しテーマの変更)はかなり良さそうです!

はい、そうではないことを私は知っています

未解決の質問が残っています:WebSocketが情報を順不同で配信できると予想されますか?または、サーバー側(またはAlchemy)での実装に問題がありますか。時間があるときにさらに調査します。

解決!

私はそれを考え出した!多くのテストを行った後、Connectionオブジェクト(新しいデータのデータセットを監視し、接続の構成方法に応じて適切に送信する)がTimerオブジェクトを使用して実装されていることに気付きました。これは私が例から取ったものでした(通常、私はほとんどの非同期でThreadオブジェクトを使用します)。

Timerオブジェクトの速度が上がると、Tick関数への以前の呼び出しとは非同期に実行を開始します。これは、非常にまれに、そのTick関数への1つの呼び出しが別の呼び出しよりも少し速く発生することを意味します(Alchemy Send関数のレイテンシーのため)。これにより、マイナーな故障の問題が発生します。

通信ループの実装をTimerオブジェクトからThreadオブジェクトに切り替えて同期を強制すると、順序が正しくないパケットがなくなりました。

4

3 に答える 3

1

Websocket は TCP を使用し、TCP はデータが順番に配信されることを保証します。

ブラウザが Websocket メッセージイベントを順番に起動することを願っています。私のテストでは、これが当てはまるようでした。

この単純な Node アプリを使用してテストします。

var sio = require('socket.io')
    , http = require('http')
    , express = require('express')
    , app = express()
    , srv = http.createServer(app)
    , io = sio.listen(srv)
    , fs = require('fs')
    , idx = fs.readFileSync('index.html').toString()
    ;

app.get('/', function(req, res) {
    res.send(idx);
});

var i = 0;
setInterval(function() {
    io.sockets.emit('count', i++);
}, 1);

srv.listen(888);

これは、メッセージごとにインクリメントされた数を使用して、Websocket メッセージをできるだけ速く送信するだけです。クライアント:

<script src="/socket.io/socket.io.js"></script>
<script>
var last = 0;
var socket = io.connect('/');
socket.on('count', function(d) {
    if (d-1 != last) console.warn('out of order!', last, d);
    last = d;
});
</script>

前のメッセージよりも 1 つ大きくない数を含むメッセージを受信した場合、コンソール警告をスローします。

Chrome と Firefox では、順不同のメッセージはゼロでした。

また、メッセージ受信イベント ( ) でしばらくブロックして、for (var i = 0; i < 1000000; i++) { }メッセージがキューに入る作業をシミュレートしてみました。メッセージ イベントは引き続き順番に発生します。

言い換えれば、それはあなたのセットアップの別のものです。ほとんどの場合、Alchemy サーバーは実際には異なる順序でメッセージを送信しています。

于 2013-02-08T00:18:55.193 に答える
0

タスクが同期の場合、非同期コールバックを持つTimerのようなオブジェクトを使用しないでください。スレッドを使用して、その方法で通信ループを実行します。

于 2013-02-08T22:11:58.313 に答える
0

問題がいつ投稿されたかはわかりません。私も同様の問題を抱えています。私は Alchemy Client を使用して小さなデータを送信していますが、問題はありません。チャットサービスの例はたくさんあります。しかし、4 KB (正確ではありません) を超えるファイルを送信すると、問題が発生します。私は何が起こったのかを見つけようとします。Alchemy クライアントから 0 ~ 7000 の数字を送信し、 から受信したプログラムを作成しました。508番目の位置について余分に取得UserContext.DataFrame(onreceive)されることが起こります。その後、この位置以降、データの順序が間違っています。nuget の 2.2.1 を使用しました。GiHub でバージョン 2.0 を読みました。ソースコードは機能しません。というわけで、古くて参考値なし。DataFrame.ToString"\0\0\0\0"

于 2015-11-13T10:02:16.600 に答える