1

I'm having a good old play with

  • Redis
  • Webdis
  • Dart

I wrote this

#import('dart:html');
#import('dart:json');

class ChatClient {
  XMLHttpRequest listener;
  int parsePosition = 0;

  void connect(){
    this.listener = new XMLHttpRequest();
    this.listener.open("GET", "http://i.target.co.uk:9005/subscribe/test.json", true);
    this.listener.setRequestHeader('Accept', 'application/json');
    this.listener.on.readyStateChange.add(handleData);
    this.listener.send();
  }

  void handleData(Event event){
    print(this.listener.responseText);
    /*
    if (this.listener.responseText != ""){
      Map data = JSON.parse(this.listener.responseText);
      print(data["subscribe"]);
    }
    */
  }
}

void main(){
  ChatClient client = new ChatClient();
  client.connect();
  document.query('#status').innerHTML = 'Loaded!';
}

Problem is, everytime I publish something the responseText simply grows in size like so

{"subscribe":["subscribe","test",1]}
{"subscribe":["subscribe","test",1]}{"subscribe":["message","test","e"]}
{"subscribe":["subscribe","test",1]}{"subscribe":["message","test","e"]}{"subscribe":["message","test","e"]}

Now you can't parse

{"subscribe":["subscribe","test",1]}{"subscribe":["message","test","e"]}{"subscribe":["message","test","e"]}

So what do I do? Can you clear the responseText? Flush the buffer? Something?

EDIT: I am aware you could iterate the entire string or keep track of the length of each json object but is there not a cleaner way?

Edit: With the new print statements

readyStat: 2 status: 200
{"subscribe":["subscribe","test",1]}
readyStat: 3 status: 200
{"subscribe":["subscribe","test",1]}{"subscribe":["message","test","e"]}
readyStat: 3 status: 200
Jakob Bowyer
  • 33,878
  • 8
  • 76
  • 91

2 Answers2

1

Edit 2: This stack overflow question has a similar problem to the readyState change: Ajax readystate 3 (Chrome / IE) - I'm stuggling for more decent assistance.


Edit: I think I've led you up the garden path a little - The response status of the ajax request states (3) its still loading/receiving the information.

This isn't directly applied to your question, but I feel it's apart of the problem.

I have a quick scan of http://www.w3.org/TR/2006/WD-XMLHttpRequest-20060405/ And I spotted: `readyState of type unsigned short, readonly The state of the object. The attribute MUSt be one of the following values:

0 Uninitialized
    The initial value.
1 Open
    The open() method has been successfully called.
2 Sent
    The UA successfully completed the request, but no data has yet been received.
3 Receiving
    Immediately before receiving the message body (if any). All HTTP headers have been received.
What about HEAD requests?
4 Loaded
    The data transfer has been completed.

So in stage 3 we have responseText holding the partial data.

from http://jszen.blogspot.co.uk/2005/03/xmlhttp-and-readystate.html:

... the URI /some/uri can establish a persistent connection, which means that unless the connection is terminated by the script or the server, readyState will always be 3 (interactive). According to the docs, I should be able grab the incomplete response from the server at this time, but apparently not ...


On msdn, I spotted this http://msdn.microsoft.com/en-us/library/ie/ms534361(v=vs.85).aspx:

You cannot call responseBody and responseText properties to obtain partial results (readyState = 3). Doing so will return an error, because the response is not fully received. You must wait until all data has been received.


First answer:

void handleData(Event event){
  print(this.listener.responseText);

  int a = this.listener.readyState;
  int b = this.listener.status;
  print("readyStat: $a status: $b");

  if (this.listener.readyState == 4 && this.listener.status == 200) {
    if (this.listener.responseText != ""){
      Map data = JSON.parse(this.listener.responseText);
      print(data["subscribe"]);
    }
  }
}

On the receiver object, you'll have a readyState and a status. If you wait till these are in a state of completion readyState == 4 and status==200 your data may be complete when your done.

This is untested as I haven't the right environment to test this

Community
  • 1
  • 1
Glycerine
  • 7,157
  • 4
  • 39
  • 65
0

Final solution used.

  void connect(){
    this.listener = new XMLHttpRequest();
    this.listener.open("GET", "http://i.h.co.uk:9005/subscribe/test", true);
    this.listener.setRequestHeader('Accept', 'application/json');
    this.listener.on.readyStateChange.add(handleData);
    this.listener.send(); 
  }

  void handleData(Event event){
    try {
      Map data = JSON.parse(this.listener.responseText.substring(this.parsePosition));
      this.parsePosition = this.listener.response.length;
      var message = data['subscribe'][2];
      print("Recieved> $message");
    } catch (final e){
    }
  }
Jakob Bowyer
  • 33,878
  • 8
  • 76
  • 91