Add TCP client example. Separate 'log' from 'print'.

parent 200c5f47
function (imports) {
if (imports.thread.id() > 0) return;
var netLib = imports.netLib;
var schedule = imports.scheduler.append;
var log = imports.log.log;
var print = imports.stdio.print;
// Start the netLib library
netLib.netInit();
var clientsocket = netLib.netInitSocket();
netLib.netConnect(clientsocket, 'dns.google.com', 80);
var stream = imports.streams.TCPDuplexStream(clientsocket);
var UTF8decoder = new TextDecoder('utf-8')
var UTF8encoder = new TextEncoder('utf-8')
// Setup echo server
stream.sink(function (end, cb) {
var request = 'GET /resolve?name=dns.google.com&type=A HTTP/1.1' + '\r\n' +
'Host: dns.google.com' + '\r\n' +
'Accept: application/json' + '\r\n\r\n'
var bytes = UTF8encoder.encode(request);
cb(null, bytes)
})
stream.source(null, function (err, buffer) {
var text = UTF8decoder.decode(new Uint8Array(buffer));
// TODO: use fancier HTTP parser?
// For now: sloppy HTTP body parser!
try {
text = text.slice(text.indexOf('{'), text.lastIndexOf('}')+1)
log(text);
var json = JSON.parse(text);
log(json);
print(json.Answer[0].data + '\n');
} catch (err) {
log('Could not parse JSON response')
}
// Stop the netLib library
netLib.netStop();
})
}
......@@ -5,7 +5,7 @@ function (imports) {
var Queues = imports.Queues;
var timers = Queues.timers;
var compile = imports.sandbox.compileTrustedFunction;
var print = imports.stdio.print
var print = imports.log.log
if (imports.thread.id() !== 0) return
......
......@@ -4,7 +4,7 @@ function (imports) {
var Queues = imports.Queues;
var timers = Queues.timers;
var compile = imports.sandbox.compileTrustedFunction;
var print = imports.stdio.print
var print = imports.log.log
var netLib = imports.netLib
var port = 8080;
......
function (imports) {
if (imports.thread.id() % 2 === 0) {
imports.thread.sleep(5000)
imports.stdio.print(imports.thread.id() + ': ' + 'ha')
imports.log.log(imports.thread.id() + ': ' + 'ha')
} else {
for (var i = 0; i < 5; i++) {
imports.stdio.print(imports.thread.id() + ': ' + i)
imports.log.log(imports.thread.id() + ': ' + i)
imports.thread.sleep(1000 * Math.random())
}
}
......
......@@ -6,7 +6,7 @@ function (imports) {
var c;
while (true) {
c = imports.stdio.getchar()
imports.stdio.print(thread + ': ' + c)
imports.log.log(thread + ': ' + c)
if (c instanceof Error) break
imports.thread.sleep(100)
}
......
......@@ -11,8 +11,8 @@ function (imports) {
if (c instanceof Error) break
if (c === undefined) imports.thread.sleep(100)
if (c > 0) {
imports.stdio.print(thread + ': read ' + c + ' bytes')
imports.stdio.print(UTF8decoder.decode(buffer.subarray(0, c)))
imports.log.log(thread + ': read ' + c + ' bytes')
imports.log.log(UTF8decoder.decode(buffer.subarray(0, c)))
}
}
}
......
......@@ -29,19 +29,19 @@ function (imports) {
var chars = []
readUnicode(null, function next(end, char) {
if (end) throw end
imports.stdio.print(char)
imports.log.log(char)
schedule([readUnicode, null, next])
// readUnicode(null, next)
})
var i = 0;
try {
while (true) {
imports.stdio.print("Tick count: " + i)
imports.log.log("Tick count: " + i)
tick()
i++
}
} catch (e) {
imports.stdio.print(e)
imports.log.log(e)
}
}
}
function app (imports) {
if (imports.thread.id() === 0) {
var server = imports.streams.TCPDuplexSourceStream({port: 8080, host: 'localhost'});
imports.stdio.print('test 1')
imports.log.log('test 1')
var onConnection = function onConnection (err, connection) {
imports.stdio.print('test 2')
imports.log.log('test 2')
// Setup echo server
connection.sink(connection.source)
imports.scheduler.append([server, null, onConnection])
......
......@@ -14,6 +14,6 @@ function (imports) {
// probably necessary to be compatible with ye olde node.
global.dir = imports.modules.dir
var testme = imports.sandbox.compileTrustedFunction('subexample/grandchild.js');
imports.stdio.print(JSON.stringify(testme(3, 4)));
imports.stdio.print(JSON.stringify(testme(3, 4)) + '\n');
return
}
......@@ -5,7 +5,7 @@ function (imports) {
var Queues = imports.Queues;
var timers = Queues.timers;
var compile = imports.sandbox.compileTrustedFunction;
var printTime = compile('printTime.js')(imports.stdio.print);
var printTime = compile('printTime.js')(imports.log.log);
var orderedInsert = compile('orderedInsert.js')();
var byMstimestampAscending = function (a, b) {
return a.t - b.t;
......
......@@ -12,6 +12,7 @@ function (imports) {
imports.streams = {}
imports.streams.ByteDuplexStream = imports.sandbox.compileTrustedFunction('streams/byte-duplex-stream.js')(imports)
imports.streams.UnicodeThroughStream = imports.sandbox.compileTrustedFunction('streams/unicode-through-stream.js')(imports)
imports.streams.TCPDuplexStream = imports.sandbox.compileTrustedFunction('streams/tcp-duplex-stream.js')(imports)
imports.streams.TCPDuplexSourceStream = imports.sandbox.compileTrustedFunction('streams/tcp-duplex-source-stream.js')(imports)
// run timeouts due
......@@ -34,7 +35,7 @@ function (imports) {
try {
while (tick()) {}
} catch (e) {
if (e.message !== "Queue complete.") imports.stdio.print(e);
if (e.message !== "Queue complete.") imports.log.log(e);
}
}
}
function (imports) {
var netLib = imports.netLib;
var print = imports.stdio.print;
var print = imports.log.log;
var schedule = imports.scheduler.append;
// TCP connection stream
function duplexStream (clientsocket) {
return {
source: function read (end, cb) {
if (end) {
// Disconnect the client
print("-- Source received end message.");
netLib.netDisconnect(clientsocket);
return
}
var buffer = Uint8Array.allocPlain(1000);
// Check for data to receive and print if there was something
try {
var bytesRead = netLib.netRecv(clientsocket, buffer);
if (bytesRead > 0) {
var croppedBuffer = buffer.subarray(0, bytesRead);
print("-- Read " + bytesRead + " bytes.");
return schedule([cb, null, croppedBuffer])
} else {
return schedule([read, end, cb])
}
} catch (err) {
// an error means the other end hung up
print("-- Source hung up!");
netLib.netDisconnect(clientsocket);
return schedule([cb, true])
}
},
sink: function reader (read) {
read(null, function next (end, data) {
if (end) {
// Disconnect the client
print("-- Sink received end message.");
netLib.netDisconnect(clientsocket);
return
}
// Send data to the client
print(data.length)
try {
var bytesWritten = netLib.netSend(clientsocket, data);
print("-- Sent " + bytesWritten + " bytes.");
return schedule([read, null, next])
} catch (err) {
// Socket no longer there (client disconnected from us)
print("-- Sink hung up!");
return schedule([read, true])
}
})
}
}
}
var TCPDuplexStream = imports.streams.TCPDuplexStream;
return function streamOfStreams (args) {
// Start the netLib library
......@@ -69,7 +18,6 @@ function (imports) {
return function read (end, cb) {
if (end) {
print('test 4: end is true')
// TODO: We need a way to kill all current connections. :/
print("That's enough for now! Bye!");
netLib.netDisconnect(listensocket);
......@@ -83,9 +31,9 @@ function (imports) {
var clientsocket = netLib.netInitSocket();
if (netLib.netAccept(listensocket, clientsocket)) {
// A client has connected!
imports.stdio.print("Hello new client!");
print("Hello new client!");
var stream = duplexStream(clientsocket);
var stream = TCPDuplexStream(clientsocket);
return cb(null, stream);
} else {
schedule([read, end, cb])
......
function (imports) {
var netLib = imports.netLib;
var print = imports.log.log;
var schedule = imports.scheduler.append;
// TCP connection stream
return function duplexStream (clientsocket) {
return {
source: function read (end, cb) {
if (end) {
// Disconnect the client
print("-- Source received end message.");
netLib.netDisconnect(clientsocket);
return
}
var buffer = Uint8Array.allocPlain(1000);
// Check for data to receive and print if there was something
try {
var bytesRead = netLib.netRecv(clientsocket, buffer);
if (bytesRead > 0) {
var croppedBuffer = buffer.subarray(0, bytesRead);
print("-- Read " + bytesRead + " bytes.");
return schedule([cb, null, croppedBuffer])
} else {
return schedule([read, end, cb])
}
} catch (err) {
// an error means the other end hung up
print("-- Source hung up!");
netLib.netDisconnect(clientsocket);
return schedule([cb, true])
}
},
sink: function reader (read) {
read(null, function next (end, data) {
if (end) {
// Disconnect the client
print("-- Sink received end message.");
netLib.netDisconnect(clientsocket);
return
}
// Send data to the client
try {
var bytesWritten = netLib.netSend(clientsocket, data);
print("-- Sent " + bytesWritten + " bytes.");
return schedule([read, null, next])
} catch (err) {
// Socket no longer there (client disconnected from us)
print("-- Sink hung up!");
return schedule([read, true])
}
})
}
}
}
}
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "duktape/duktape.h"
#include "bindings_log.h"
// For now, copying method names from 'console'.
// In future, support different transports, formats, etc.
void push_bindings_log(duk_context *ctx) {
duk_push_c_function(ctx, c_log, DUK_VARARGS);
duk_put_prop_string(ctx, -2, "log");
duk_push_c_function(ctx, c_log, DUK_VARARGS);
duk_put_prop_string(ctx, -2, "info");
duk_push_c_function(ctx, c_log, DUK_VARARGS);
duk_put_prop_string(ctx, -2, "warn");
duk_push_c_function(ctx, c_log, DUK_VARARGS);
duk_put_prop_string(ctx, -2, "error");
}
duk_ret_t c_log(duk_context *ctx) {
duk_push_string(ctx, " ");
duk_insert(ctx, 0);
duk_join(ctx, duk_get_top(ctx) - 1);
fprintf(stderr, "%s\n", duk_safe_to_string(ctx, -1));
return 0;
}
......@@ -5,7 +5,7 @@
#include "bindings_stdio.h"
void push_bindings_stdio(duk_context *ctx) {
duk_push_c_function(ctx, c_print, DUK_VARARGS);
duk_push_c_function(ctx, c_print, 1);
duk_put_prop_string(ctx, -2, "print");
duk_push_c_function(ctx, c_getchar, 0);
duk_put_prop_string(ctx, -2, "getchar");
......@@ -18,10 +18,7 @@ void push_bindings_stdio(duk_context *ctx) {
}
duk_ret_t c_print(duk_context *ctx) {
duk_push_string(ctx, " ");
duk_insert(ctx, 0);
duk_join(ctx, duk_get_top(ctx) - 1);
printf("%s\n", duk_safe_to_string(ctx, -1));
fprintf(stdout, duk_safe_to_string(ctx, -1));
return 0;
}
......@@ -70,7 +67,6 @@ duk_ret_t c_putchar (duk_context *ctx) {
return duk_error(ctx, 999, "Unhandled situation in c_putchar.");
}
duk_ret_t c_getbuffer (duk_context *ctx) {
char * buffer;
duk_size_t length;
......
......@@ -86,6 +86,10 @@ int main(int argc, char *argv[] /* char *environ[] */) {
duk_push_object(ctx);
push_bindings_stdio(ctx);
duk_put_prop_string(ctx, -2, "stdio");
// Provide access to console.log
duk_push_object(ctx);
push_bindings_log(ctx);
duk_put_prop_string(ctx, -2, "log");
// Provide access to threading primitives
duk_push_object(ctx);
push_bindings_thread(ctx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment