bramblex / niva

一个基于 Tauri WRY 跨端 Webview 库的超轻量极易用的跨端应用开发框架。
https://bramblex.github.io/niva/
MIT License
637 stars 36 forks source link

Question: Use as window in node? #17

Open tiptronic opened 1 year ago

tiptronic commented 1 year ago

Hi there,

I hope it's okay to write in english!

I just found this project, which is very interesting! Unfortunately I am unable to read chinese and Google Translator only helps very limited.

So here's my question:

Would it be possible to use niva as window for a node.js application? - It would talk to Node via Websockets?

If yes - how could I try that? (The developer-tool is pretty hard to use, because I haven't found a way to translate the buttons and infos).

I'm on MacOS 13.3.1

bramblex commented 1 year ago

Of course, you can use Niva like a normal web browser with a Node.js backend. Websocket is also supported.

Just download the App and copy the executable file in your project. The position of the executable file is NivaDevtools.app/Contents/MacOS/NivaDevtools, and it is actually the raw Niva executable file. If you want to use Niva with Node.js on Windows, you will need to compile an Niva executable yourself because the NivaDevtools on Windows includes a lot of resources in the exe file.

There is an example:

const http = require('http');
const path = require('path');
const childProcess = require('child_process');
const fs = require('fs');

const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/html');
  res.end("<h1>Hello World</h1><script>Niva.api.dialog.showMessage('hello', 'hello world');</script>");
});

const port = 3000;
server.listen(port, () => {
  console.log(`server is listening on port ${port}`);

  // create a niva config file
  const nivaResource = path.join(__dirname, '.niva_resource');
  const nivaConfig = path.join(nivaResource, 'niva.json');

  fs.mkdirSync(nivaResource, { recursive: true });
  fs.writeFileSync(nivaConfig, JSON.stringify({
    name: "NivaWindow",
    uuid: Math.random().toString(),
  }))

  const nivaWindow = childProcess.spawn(path.join(__dirname, 'niva'), [
    `--debug-config=${nivaConfig}`, // path to the config file
    `--debug-resource=${nivaResource}`, // path to the config file
    `--debug-entry=http://localhost:${port}`, // url to the entry point wich niva window will open
    `--debug-devtools=true` // enable devtools
  ]);

  nivaWindow.stdout.on('data', (data) => {
    console.log(`stdout: ${data}`)
  })

  nivaWindow.stderr.on('data', (data) => {
    console.error(`stderror: ${data}`)
  })

  nivaWindow.on('close', () => {
    server.close();
  })
})

To be a Node.js window library is also one of Niva's design goals. I will implement it in the future and translate the documents into English as well.

The latest version(v0.9.9) supports English. Please click on the buttons at the bottom left to toggle it. :)

xiaogesang commented 1 year ago

6,大佬英文这么好 Good Good

tiptronic commented 1 year ago

hi @bramblex ,

thanks for the reply and great job!! - your new version now looks much better and it does work pretty good.

Is this snippet:

 fs.mkdirSync(nivaResource, { recursive: true });
  fs.writeFileSync(nivaConfig, JSON.stringify({
    name: "NivaWindow",
    uuid: Math.random().toString(),
  }))

required to operate the niva binary, or is this just for debugging?

Now I just have to figure out how to ideally communicate with my index.js (WebSocket or stdin/out) - I have no clues (atm) how communication via stdin/stdout would work in this case...

thx again !!

bramblex commented 1 year ago

When Niva starts up, it requires a resource directory and a niva.json file in the current version. So this code is not just for debugging.

For communication between Node.js and Niva Webview, I suggest using WebSocket. Currently, Niva does not support communication with stdin or stdout. You can use a WebSocket library like ws to achieve this easily. https://www.npmjs.com/package/ws

tiptronic commented 1 year ago

Great info - thanks!

can the uuid be static? (I mean: can I just add 'yadda.yadda.bang.bang' as uuid? (I usually can't write to the file-system, because of permissions).

And thanks for the info on ws (that's what I'm using anyway - I was just curious if I can get something more ipc-like to work when using stdin/stdout)

bramblex commented 1 year ago

You can create a static resource directory and a niva.json file with your project, and you can also generate a unique UUID online using an online generator like https://www.uuidgenerator.net/version4.

I think Http or WebSocket is the best way for communication between different process if we are not particularly concerned about performance. Otherwise, we need to design a complex communication protocol. This is not worth it. 😭

tiptronic commented 1 year ago

Thanks again for the info on the static resource. Meanwhile I have everything working properly - that's really great!

Now I'm going to play with the Niva.api and see what else is possible :)

Really very good job!!

tiptronic commented 1 year ago

Btw - you are right: there's really no need to create a separate communication layer.

For me it is (somewhat) important, the executable stays lightweight... that makes it easier to share/deploy.

bramblex commented 1 year ago

Btw - you are right: there's really no need to create a separate communication layer.

For me it is (somewhat) important, the executable stays lightweight... that makes it easier to share/deploy.

Yes, your right. I only considered Node.js developpers who have the http module built-in, without considering that other runtimes may not have the http module built-in. If developoers from other languages or runtimes, such as C language develpoers, also want to use Niva, they would have to require an http module to communicate with Niva webview.

However, all programs have stdin and stdout, so I'm considering whether it's possible to support communicate using stdin and stdout.

tiptronic commented 1 year ago

I guess, stdin / stdout would be a nice thing to have - especially if it's optional (I'm not sure if this is important). I think you are right: the most flexible use-case (and likely the most-used) is the node:http combo. If I can help you with something here - just let me know...