|
@@ -35,13 +35,14 @@ class Socket {
|
|
static var openedSocks = [];
|
|
static var openedSocks = [];
|
|
#if flash
|
|
#if flash
|
|
var s : flash.net.Socket;
|
|
var s : flash.net.Socket;
|
|
|
|
+ #elseif hl
|
|
|
|
+ var s : #if (haxe_ver >= 4) hl.uv.Stream #else Dynamic #end;
|
|
|
|
+ #elseif (nodejs && hxnodejs)
|
|
|
|
+ var s : js.node.net.Socket;
|
|
#end
|
|
#end
|
|
#if (flash && air3)
|
|
#if (flash && air3)
|
|
var serv : flash.net.ServerSocket;
|
|
var serv : flash.net.ServerSocket;
|
|
#end
|
|
#end
|
|
- #if hl
|
|
|
|
- var s : #if (haxe_ver >= 4) hl.uv.Stream #else Dynamic #end;
|
|
|
|
- #end
|
|
|
|
public var out(default, null) : SocketOutput;
|
|
public var out(default, null) : SocketOutput;
|
|
public var input(default, null) : SocketInput;
|
|
public var input(default, null) : SocketInput;
|
|
public var timeout(default, set) : Null<Float>;
|
|
public var timeout(default, set) : Null<Float>;
|
|
@@ -149,6 +150,18 @@ class Socket {
|
|
close();
|
|
close();
|
|
throw e;
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
+ #elseif (nodejs && hxnodejs)
|
|
|
|
+ js.node.Net.createServer(function(sock) {
|
|
|
|
+ var s = new Socket();
|
|
|
|
+ s.s = sock;
|
|
|
|
+ s.out = new NodeSocketOutput(s);
|
|
|
|
+ s.input = new NodeSocketInput(s);
|
|
|
|
+ openedSocks.push(s);
|
|
|
|
+ onConnect(s);
|
|
|
|
+ }).on('error', function(e) {
|
|
|
|
+ close();
|
|
|
|
+ throw e;
|
|
|
|
+ }).listen(port, host, listenCount);
|
|
#else
|
|
#else
|
|
throw "Not implemented";
|
|
throw "Not implemented";
|
|
#end
|
|
#end
|
|
@@ -168,6 +181,12 @@ class Socket {
|
|
out = new SocketOutput();
|
|
out = new SocketOutput();
|
|
s = null;
|
|
s = null;
|
|
}
|
|
}
|
|
|
|
+ #elseif (nodejs && hxnodejs)
|
|
|
|
+ if( s != null ) {
|
|
|
|
+ s.destroy();
|
|
|
|
+ out = new SocketOutput();
|
|
|
|
+ s = null;
|
|
|
|
+ }
|
|
#end
|
|
#end
|
|
}
|
|
}
|
|
|
|
|
|
@@ -354,4 +373,103 @@ class HLSocketInput extends SocketInput {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-#end
|
|
|
|
|
|
+#elseif (nodejs && hxnodejs)
|
|
|
|
+
|
|
|
|
+class NodeSocketOutput extends SocketOutput {
|
|
|
|
+
|
|
|
|
+ var tmpBuf : js.node.Buffer;
|
|
|
|
+ var s : Socket;
|
|
|
|
+
|
|
|
|
+ public function new(s) {
|
|
|
|
+ super();
|
|
|
|
+ this.s = s;
|
|
|
|
+ @:privateAccess s.s.on('error', () -> writeResult(false));
|
|
|
|
+ @:privateAccess s.s.on('end', () -> s.close());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function writeResult(b) {
|
|
|
|
+ if( !b ) {
|
|
|
|
+ s.close();
|
|
|
|
+ s.onError("Failed to write data");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override function writeByte(c:Int) {
|
|
|
|
+ if( tmpBuf == null )
|
|
|
|
+ tmpBuf = js.node.Buffer.alloc(1);
|
|
|
|
+ tmpBuf.fill(c);
|
|
|
|
+ @:privateAccess s.s.write(tmpBuf);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override function writeBytes(buf:haxe.io.Bytes, pos:Int, len:Int):Int {
|
|
|
|
+ @:privateAccess s.s.write(buf.sub(pos, len).b);
|
|
|
|
+ return len;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+class NodeSocketInput extends SocketInput {
|
|
|
|
+
|
|
|
|
+ var s : Socket;
|
|
|
|
+ var data : js.node.Buffer;
|
|
|
|
+ var pos : Int = 0;
|
|
|
|
+ var len : Int = 0;
|
|
|
|
+ var size : Int = 0;
|
|
|
|
+
|
|
|
|
+ public function new(sock) {
|
|
|
|
+ this.s = sock;
|
|
|
|
+ @:privateAccess s.s.on('data', buf -> onData(buf, buf.length));
|
|
|
|
+ @:privateAccess s.s.on('end', () -> onData(js.node.Buffer.from([]), -4095));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function onData(buf:js.node.Buffer, recv:Int) {
|
|
|
|
+ if( recv < 0 ) {
|
|
|
|
+ s.close();
|
|
|
|
+ s.onError("Connection closed");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (data == null)
|
|
|
|
+ data = js.node.Buffer.alloc(len - pos);
|
|
|
|
+ var req = pos + len + recv;
|
|
|
|
+ if( req > size && pos >= (size >> 1) ) {
|
|
|
|
+ data.copy(data, 0, pos, pos+len);
|
|
|
|
+ pos = 0;
|
|
|
|
+ req -= pos;
|
|
|
|
+ }
|
|
|
|
+ if( req > size ) {
|
|
|
|
+ var nsize = size == 0 ? 1024 : size;
|
|
|
|
+ while( nsize < req ) nsize = (nsize * 3) >> 1;
|
|
|
|
+ var ndata = js.node.Buffer.alloc(nsize);
|
|
|
|
+ data.copy(ndata, 0, pos, pos+len);
|
|
|
|
+ data = ndata;
|
|
|
|
+ size = nsize;
|
|
|
|
+ pos = 0;
|
|
|
|
+ }
|
|
|
|
+ buf.copy(data, pos + len, 0, recv);
|
|
|
|
+ len += recv;
|
|
|
|
+ s.onData();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override function get_available() {
|
|
|
|
+ return len;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override function readByte():Int {
|
|
|
|
+ if( len == 0) throw new haxe.io.Eof();
|
|
|
|
+ var c = data[pos++];
|
|
|
|
+ len--;
|
|
|
|
+ return c;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override function readBytes(s:haxe.io.Bytes, pos:Int, len:Int):Int {
|
|
|
|
+ if( pos < 0 || len < 0 || pos + len > s.length ) throw haxe.io.Error.OutsideBounds;
|
|
|
|
+ var max = len < this.len ? len : this.len;
|
|
|
|
+ data.copy(@:privateAccess s.b, pos, this.pos, this.pos+max);
|
|
|
|
+ this.pos += max;
|
|
|
|
+ this.len -= max;
|
|
|
|
+ return max;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#end
|