Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async comunication with javascript #6115

Open
jcubic opened this issue Jan 18, 2018 · 4 comments
Open

Async comunication with javascript #6115

jcubic opened this issue Jan 18, 2018 · 4 comments

Comments

@jcubic
Copy link

jcubic commented Jan 18, 2018

Here is a question on SO How can I run an interactive program compiled with Emscripten in a web page?

And I came up with a hack that allows to send asynchronous messages from C to javascript and get the value from JS in C. So I can use it with the jQuery Terminal read method.

I've abused the fetch API and created a wrapper over XHR in JS that sends real XHR or my code if the URL is in a special format. The code can be found here

https://gist.github.com/jcubic/87f2b4c5ef567be43796e179ca08c0da

Does a better solution exist? Or will you consider adding this to emscripten to allow for Bidirectional async communication with javascript?

I was thinking about something like

void read_async();

void success(void *text) {
   printf("input: %s\n", text);
   read_async();
}

void fail() {
   printf("fail\n");
}


void read_async() {
   char** args = {"name: "};
   emscripten_async_js("read", args, &success, &fail);
}

int main() {
  read_async();
}

and in JS the code can execute global read function and if returned promise resolve it will execute success in C with data like this:

function read(prompt) {
   display(prompt);
   return new Promise(function(resolve, reject) {
      if (true) {
         resolve("hello");
      } else {
         reject();
   });
}

and it will execute C function success with the string "hello".

@xloem
Copy link
Contributor

xloem commented Apr 3, 2020

It looks like a lot of the js libraries used in emterm could be made more general to allow for interoperation with e.g. xterm as a normal terminal. I started this a little at https://github.com/xloem/emterm . with more dev work from somebody, terminal applications could be running in the browser.

Emterm lets the user change up their js libraries with --js-library .

@jcubic jcubic mentioned this issue Dec 29, 2020
@gaycodegal
Copy link

gaycodegal commented Jun 26, 2022

Synchronous terminal communication is possible now thanks to emscripten asyncify.
Code demonstration
https://github.com/gaycodegal/lua-repl

Live demo
https://gaycodegal.github.io/lua-repl

@TheGeekOnSkates
Copy link

Asyncify is great, but how then would I point fgets or getchar or whatever at it? I mean I suppose you could pretend you're building an OS from scratch - no standard library, no standard anything - and re-implement these functions as Asyncify-based stdin... but is that really the best way? If it is, it is. fgets is out, custom hacks like the OP's read_async or whatever is in. Forget anything like GNU Readline. 😆

Another thing I've had limited success with is by hacking the "compiled" Javascript and redefining stdin and stdout (a thing I have to redo EVERY TIME I BUILD - so annoying - sorry). For example, I can redefine console.log to run xterm.js's output function, like I did on one of my projects, but stdin is much much harder. I've tried redefining prompt to return the next character in a buffer, or 0 if there was none, and then use a while-loop in C to wait for input... nope. It hung the main thread. So apparently it's Asyncify or bust? ☹️

There's another option, one I've been trying to avoid but might have to be the way to go: SDL. SDL is great for games, and has keyboard event handling, so maybe if I geek-rigged a terminal in SDL, maybe then I could just use stdin as stdin... Obviously I'd rather not reinvent that wheel, but IMO something really needs to be done to make stdin more usable. Sorry, I know this sounds an awful lot like a rant, but this single issue has kept me from using Emscripten in any meaningful way since I found it 3-4 years ago. That's why I'm taking the time to add to this question/issue/whatever. Thank you for reading, and for all the awesome work you guys do to make WebAssembly accessible to us C programmers. :)

@gaycodegal
Copy link

Readline is totally something you can emulate in wasm, I do it for my own project. You just need to write your own headers and define functions with the same API as readline. I didn't bother to implement the history part of readline, as that's just extra JavaScript work, but it's totally doable too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants