OpenFL: URLLoader() alternative using raw socket

August 21, 2014 ยท View on GitHub

package ;

import haxe.Timer; import openfl.net.URLLoader; import openfl.net.URLRequest; import openfl.events.*; import haxe.Json; import haxe.io.Bytes;

using StringTools;

#if neko typedef Thread = neko.vm.Thread; typedef Lib = neko.Lib; #elseif cpp typedef Thread = cpp.vm.Thread; typedef Lib = cpp.Lib; #end

class SyncManager { public static var do_log:Bool = true;

#if android public static var server_url:String = 'http://10.0.2.2'; #else public static var server_url:String = 'http://localhost'; #end

public static function sync() {
log('Starting sync...');

//Thread.create(function()
//{
    //syncStateUsingURLLoader();
    syncStateUsingSocket();
//});

}

static function syncStateUsingSocket() { log('Sync state using socket...');

var host = server_url.substr('http://'.length);
var s = new sys.net.Socket();
s.connect(new sys.net.Host(host), 80);
s.output.writeString('GET /products.csv HTTP/1.0\r\n');
s.output.writeString('Host: ' + host + '\r\n');
s.output.writeString('\r\n');

var headers = new Map<String, String>();
while (true)
{
  var ln = s.input.readLine().trim();
  if (ln == '') break;
 
  var a = ln.split(':');
  var key = a.shift().toLowerCase();
  headers[key] = a.join(':');      
}

if (headers['content-length'] == null) {
  return;
}

var len = Std.parseInt(headers['content-length']);
if (!(len > 0)) {
  return;
}

var t = Timer.stamp();
var content:String = '';
var buf = Bytes.alloc(len);    
var block_len = 1024 * 1024;   // BLOCK SIZE: small value (like 64 KB) causes slow download
var nblocks = Math.ceil(len / block_len);
var bytes_left = len;
var bytes_loaded = 0;

for (i in 0...nblocks)
{
  var actual_block_len = (bytes_left > block_len) ? block_len : bytes_left;
  s.input.readFullBytes(buf, bytes_loaded, actual_block_len);
  bytes_left -= actual_block_len;
  
  bytes_loaded += actual_block_len;      
  trace(Math.round(bytes_loaded / len * 1000) / 10 + '%');      
}
    
trace('string len = ' + buf.toString().length);
trace('t = ' + (Timer.stamp() - t) + 's');
s.close();

}

static function syncStateUsingURLLoader() { log('Sync state using URLLoader...');

var t = Timer.stamp();

var loader = new URLLoader();

loader.addEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent)
{
  var p = e.bytesLoaded / e.bytesTotal;
  trace('progress = ' + Math.round(p * 1000) / 10 + '%');
});

loader.addEventListener(Event.COMPLETE, function(e:Event)
{
  trace('t = ' + (Timer.stamp() - t) + 's');
});    

loader.load(new URLRequest(server_url + '/products.csv'));    

}

static inline function log(s:String) { if (do_log) { trace(s); } } }