tcpip.js networking examples / docs
- Dominant language
- JavaScript
- Stars
- 23.5k
- Forks
- 1.9k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 7
Description
Hey 👋 amazing tool.
So far the networking examples focus on connecting to external networks or proxies (fetch proxy, WISP). I'm interested in local networking - communicating directly between JS and v86. This would open the door to use cases like running a server-side program (like Postgres, nginx, etc) inside v86 and communicate with it from JS.
I built [tcpip.js](https://github.com/chipmk/tcpip.js/) to solve this. It's a virtual network stack that can run in the browser. It's built on top of [lwIP](https://github.com/lwip-tcpip/lwip) compiled to WASM with bindings to hook into each layer of the network stack (L2, L3, L4).
### Example use case
Set up plumbing that pipes ethernet packets between v86 and the virtual network stack.
```ts
import { createStack } from 'tcpip';
import { createV86NetworkStream } from '@tcpip/v86';
const stack = await createStack();
// Tap interfaces hook into ethernet (L2) frames
const tapInterface = await stack.createTapInterface({
mac: '01:23:45:67:89:ab',
ip: '192.168.1.1/24',
});
const emulator = new V86();
// Adds net0 listener and exposes as readable/writable streams
const vmNic = createV86NetworkStream(emulator);
// Forward frames between the tap interface and the VM's NIC
tapInterface.readable.pipeTo(vmNic.writable);
vmNic.readable.pipeTo(tapInterface.writable);
```
Now we can establish a TCP connection to the emulator from JS (assuming VM has IP `192.168.1.2` and a server listening on port 80):
```ts
const connection = await stack.connectTcp({
host: '192.168.1.2',
port: 80,
});
// connection.writable is a standard WritableStream
const writer = connection.writable.getWriter();
// Send data
await writer.write(new TextEncoder().encode('Hello, world!'));
await writer.close();
// Listen for incoming data
for await (const chunk of connection) {
console.log(new TextDecoder().decode(chunk));
}
```
Or we can create a TCP server and listen for inbound connections:
```ts
const listener = await stack.listenTcp({
port: 80,
});
// TcpListener is an async iterable that yields TcpConnections
for await (const connection of listener) {
const writer = connection.writable.getWriter();
// Send data
await writer.write(new TextEncoder().encode('Hello, world!'));
await writer.close();
// Listen for incoming data
for await (const chunk of connection) {
console.log(new TextDecoder().decode(chunk));
}
}
```
### Other use cases
I'm planning to add bridge interface support soon, which would allow you to use tcpip.js as a switch/router. This can be useful for connecting more than 2 VMs together in a LAN.
---
I was wondering if you are interested in adding docs / examples for this use case? If so happy to put a PR together that adds some demos and networking docs.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.