Autor Beitrag
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Di 29.04.14 11:21 
Hey Leute,

ich arbeite zur Zeit an einer Webseite die über WebSockets Daten mit dem Server austauscht. Das läuft so ab, das die Seite mehere Request (auf einmal) an den Server sendet und der diese dann alle nacheinander (nicht parallel) beantwortet. Nun habe ich das Problem, das ab und zu Packete verloren gehen (zumindest bekomm ich für das Packet kein WebSocket.onmessage Event), was ja bei TCP eigentlich nicht der Fall sein kann. Zum Test habe ich mir eine kleine Test-Seite gebaut, die den Fehlerfall nachstellt:
ausblenden volle Höhe JavaScript-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
this.packageSize            = 4096;
this.timerHandle            = 0;
this.receivedPackageSize    = 0
this.inbound                = [];
this.sendDataCnt            = 0;
this.parallelRequests       = 2;

/* Request:  uint32 (number of requested bytes ); */
/* Response: uint32 (number of send bytes); uint8[] data; */

var webSocket = new WebSocket('ws://10.1.0.92:6325', ['istest']);
webSocket.binaryType = 'arraybuffer';

function sendDataRequest()
{
    var buf  = new ArrayBuffer(4);
    var view = new DataView(buf, 0);
    view.setUint32(0this.packageSize, true);
    for (var i = 0; i < this.parallelRequests; i++)
        webSocket.send(buf);
    $('#sendDataCnt')[0].innerHTML = this.sendDataCnt++;
}

webSocket.onopen = function()
{
    $('#log')[0].innerHTML += 'connected<br/>';
    this.timerHandle = setInterval(sendDataRequest, 100);
}.bind(this);

webSocket.onmessage = function(event)
{
    this.inbound.push.apply(this.inbound, new Uint8Array(event.data));
    if (this.receivedPackageSize == 0 && this.inbound.length >= 4)
    {
        var u8Arr = new Uint8Array(new ArrayBuffer(4));
        u8Arr.set(this.inbound.slice(04));
        this.receivedPackageSize = new DataView(u8Arr.buffer).getUint32(0true);
        this.inbound = this.inbound.slice(4);
        if (this.receivedPackageSize != this.packageSize)
        {
            clearInterval(this.timerHandle);
            $('#header')[0].innerHTML = 'ERROR: receivedPackageSize = ' + this.receivedPackageSize;
        }
        else
            $('#header')[0].innerHTML = 'receivedPackageSize = ' + this.receivedPackageSize;
        $('#data')[0].innerHTML = 'waiting for data...';
    }
    else if (this.inbound.length >= this.receivedPackageSize)
    {
        var u8Arr = new Uint8Array(new ArrayBuffer(this.receivedPackageSize));
        u8Arr.set(this.inbound.slice(0this.receivedPackageSize));
        this.inbound = this.inbound.slice(this.receivedPackageSize);
        for (var i = 0; i < this.receivedPackageSize; i++)
        {
            if (u8Arr[i] != (i & 0xFF))
            {
                clearInterval(timerHandle);
                $('#data')[0].innerHTML = 'ERROR: invalid package data';
                break;
            }
        }
        $('#data')[0].innerHTML = 'data OK';
        this.receivedPackageSize = 0;
    }
}.bind(this);

webSocket.onerror = function(e)
{
    clearInterval(timerHandle);
    $('#log')[0].innerHTML += 'error<br/>';
    console.log(e);
}.bind(this);

webSocket.onclose = function()
{
    clearInterval(timerHandle);
    $('#log')[0].innerHTML += 'disconnected<br/>';
}.bind(this);

Ich denke das es daran liegt, das ich mehrere Request gleichezeitig absende und dann auf die Antworten warte. Umso mehr Requests ich auf eimal absende (siehe Zeile 19 und 20), umso schneller habe ich inkonsistente Daten. Hat das Problem schonmal jmd gehabt, oder weiß jmd wie ich das lösen kann? Eine Lösungsmöglichkeit währe es immer nur ein Request zu schicken und dann auf die Anwort zu warten. Da bei TCP-Verbindungen aber parallele Request möglich sein sollten würde ich die Lösung nur ungern (sozusagen als Notlösung) nutzen.

MfG & Thx Bergmann.

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 29.04.14 19:38 
Moin!

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
Nun habe ich das Problem, das ab und zu Packete verloren gehen (zumindest bekomm ich für das Packet kein WebSocket.onmessage Event), was ja bei TCP eigentlich nicht der Fall sein kann.
Warum solle das nicht möglich sein können? ;) Klar geht das, aber bei TCP gibt´s dann eine Fehlermeldung (im Gegensatz zu UDP). :idea:

Abgesehen davon sichert der TCP-Stream lediglich die Socket-to-Socket Strecke ab, es ist immer noch möglich (ohne entsprechende Fehlermeldung/Ereignis, je nach Implementation, du bist ja nicht direkt auf der SocketAPI) einen Paketverlust im Empfangspuffer zu erleiden - weil du z.B. nicht schnell genug die Daten abholst! :shock:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Bergmann89 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Di 29.04.14 21:17 
Hey,

OK, wenn man das so sieht hast du Recht. Allerdings würde ich von einer guten API erwarten, das sie mir bei einem Packetverlust auch ein entsprechendes Event wirft und das tut sie im meinem Fall nicht. Das mit den Daten abholen glaub ich weniger. Der WebSocket wirft ein entsprechendes Event in dem die eingetroffenen Daten als Parameter übergeben werden, also gibt es ein "per Hand abholen" sogesehen nicht. Das der Eingans-Puffer voll läuft glaub ich auch nicht, dafür habe ich zu wenig Daten (in dem Beispiel 2 x 4k aller 100ms).

MfG Bergmann.

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 29.04.14 21:21 
Moin!

Senk die Datenrate und dein Problem ist weg. Wetten? :zwinker:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.