This repository has been archived by the owner on Jun 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* browser-to-browser over relayv1 * debug * fix race condition * fixes * browser to browser * fix tests * add tests for handlers * fix dep-check * Add browser to browser example with Node and Go relays * fix browser-to-browser example * Attempt to fix example * race condition * buffer incoming streams before upgrade * update stream protocol name * Complete the browser-to-browser example * address review * clarify circuit relay code usage * fix lint * add explicit eslint dependency * fix dependencies * Implement single browser for browser-to-browser in CI * Complete playwright test for communicating browsers and add to CI * wrap errors * fix connection initiation * unskip filter test * fix Go version to 1.19 for compiling go-libp2p * fix protocol codes and update multiaddr library * skip localhost test on firefox * nicer fix * add tests example tests for firefox and chrome * Start rename (bugs) * use js relay in browser-to-browser tests * hacky fixes to tests * fix firefox issue * more fixes * fixes * fix review comments * Support dialing shorter circuit addrs * Use shorter multiaddr in example * add answerpromise * Fix README for example * Remove singleton * Type the promise * Fix comment * Refactor: Consolidate event handlers in resolveOnConnected * Nits * Update go multiaddr dep * Fix browser-to-server example * Nit * Workaround to not listen on p2p-circuit * workaround: Fix multiaddr splitting * Small rename cleanup --------- Co-authored-by: David DiMaria <info@collectivesessions.com> Co-authored-by: Marco Munizaga <git@marcopolo.io>
- Loading branch information
1 parent
28b2aad
commit add5c46
Showing
28 changed files
with
1,319 additions
and
517 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# js-libp2p-webrtc Browser to Browser | ||
|
||
This example leverages the [vite bundler](https://vitejs.dev/) to compile and serve the libp2p code in the browser. You can use other bundlers such as Webpack, but we will not be covering them here. | ||
|
||
## Build the `@libp2p/webrtc` package | ||
|
||
Build the `@libp2p/webrtc` package by calling `npm i && npm run build` in the repository root. | ||
|
||
## Running the Relay Server | ||
|
||
For browsers to communicate, we first need to run the LibP2P relay server: | ||
|
||
```shell | ||
npm run relay | ||
``` | ||
|
||
Copy one of the multiaddresses in the output. | ||
|
||
## Running the Example | ||
|
||
In a separate console tab, install dependencies and start the Vite server: | ||
|
||
```shell | ||
npm i && npm run start | ||
``` | ||
|
||
The browser window will automatically open. Let's call this `Browser A`. | ||
Using the copied multiaddress from the Go or NodeJS relay server, paste it into the `Remote MultiAddress` input and click the `Connect` button. | ||
`Browser A` is now connected to the relay server. | ||
Copy the multiaddress located after the `Listening on` message. | ||
|
||
Now open a second browser with the url `http://localhost:5173/`. Let's call this `Browser B`. | ||
Using the copied multiaddress from `Listening on` section in `Browser A`, paste it into the `Remote MultiAddress` input and click the `Connect` button. | ||
`Browser B` is now connected to `Browser A`. | ||
Copy the multiaddress located after the `Listening on` message. | ||
|
||
Using the copied multiaddress from `Listening on` section in `Browser B`, paste it into the `Remote MultiAddress` input in `Browser A` and click the `Connect` button. | ||
`Browser A` is now connected to `Browser B`. | ||
|
||
The peers are now connected to each other. Enter a message and click the `Send` button in either/both browsers and see the echo'd messages. | ||
|
||
The output should look like: | ||
|
||
`Browser A` | ||
```text | ||
Dialing '/ip4/127.0.0.1/tcp/57708/ws/p2p/12D3KooWRqAUEzPwKMoGstpfJVqr3aoinwKVPu4DLo9nQncbnuLk' | ||
Listening on /ip4/127.0.0.1/tcp/57708/ws/p2p/12D3KooWRqAUEzPwKMoGstpfJVqr3aoinwKVPu4DLo9nQncbnuLk/p2p-circuit/p2p/12D3KooW9wFiWFELqGJTbzEwtByXsPiHJdHB8n7Kin71VMYyERmC/p2p-webrtc-direct/p2p/12D3KooW9wFiWFELqGJTbzEwtByXsPiHJdHB8n7Kin71VMYyERmC | ||
Dialing '/ip4/127.0.0.1/tcp/57708/ws/p2p/12D3KooWRqAUEzPwKMoGstpfJVqr3aoinwKVPu4DLo9nQncbnuLk/p2p-circuit/p2p/12D3KooWBZyVLJfQkofqLK4op9TPkHuUumCZt1ybQrPvNm7TVQV9/p2p-webrtc-direct/p2p/12D3KooWBZyVLJfQkofqLK4op9TPkHuUumCZt1ybQrPvNm7TVQV9' | ||
Sending message 'helloa' | ||
Received message 'helloa' | ||
Received message 'hellob' | ||
``` | ||
|
||
`Browser B` | ||
```text | ||
Dialing '/ip4/127.0.0.1/tcp/57708/ws/p2p/12D3KooWRqAUEzPwKMoGstpfJVqr3aoinwKVPu4DLo9nQncbnuLk/p2p-circuit/p2p/12D3KooW9wFiWFELqGJTbzEwtByXsPiHJdHB8n7Kin71VMYyERmC/p2p-webrtc-direct/p2p/12D3KooW9wFiWFELqGJTbzEwtByXsPiHJdHB8n7Kin71VMYyERmC' | ||
Listening on /ip4/127.0.0.1/tcp/57708/ws/p2p/12D3KooWRqAUEzPwKMoGstpfJVqr3aoinwKVPu4DLo9nQncbnuLk/p2p-circuit/p2p/12D3KooWBZyVLJfQkofqLK4op9TPkHuUumCZt1ybQrPvNm7TVQV9/p2p-webrtc-direct/p2p/12D3KooWBZyVLJfQkofqLK4op9TPkHuUumCZt1ybQrPvNm7TVQV9 | ||
Received message 'helloa' | ||
Sending message 'hellob' | ||
Received message 'hellob' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>js-libp2p WebRTC</title> | ||
<style> | ||
label, | ||
button { | ||
display: block; | ||
font-weight: bold; | ||
margin: 5px 0; | ||
} | ||
div { | ||
margin-bottom: 20px; | ||
} | ||
#send-section { | ||
display: none; | ||
} | ||
input[type="text"] { | ||
width: 800px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div id="app"> | ||
<div> | ||
<label for="peer">Remote MultiAddress:</label> | ||
<input type="text" id="peer" /> | ||
<button id="connect">Connect</button> | ||
</div> | ||
<div id="send-section"> | ||
<label for="message">Message:</label> | ||
<input type="text" id="message" value="hello" /> | ||
<button id="send">Send</button> | ||
</div> | ||
<div id="connected_peer"></div> | ||
<div id="output"></div> | ||
</div> | ||
<script type="module" src="./index.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { multiaddr, protocols } from "@multiformats/multiaddr" | ||
import { pipe } from "it-pipe" | ||
import { fromString, toString } from "uint8arrays" | ||
import { webRTC } from "js-libp2p-webrtc" | ||
import { webSockets } from "@libp2p/websockets" | ||
import * as filters from "@libp2p/websockets/filters" | ||
import { pushable } from "it-pushable" | ||
import { mplex } from "@libp2p/mplex" | ||
import { createLibp2p } from "libp2p" | ||
import { circuitRelayTransport } from 'libp2p/circuit-relay' | ||
import { noise } from "@chainsafe/libp2p-noise" | ||
|
||
let webrtcDirectAddress | ||
|
||
const CIRCUIT_RELAY_CODE = 290 | ||
const WEBRTC_CODE = 281 | ||
|
||
const output = document.getElementById("output") | ||
const sendSection = document.getElementById("send-section") | ||
const peer = document.getElementById("peer") | ||
const appendOutput = (line) => { | ||
const div = document.createElement("div") | ||
div.appendChild(document.createTextNode(line)) | ||
output.append(div) | ||
} | ||
const clean = (line) => line.replaceAll("\n", "") | ||
const sender = pushable() | ||
|
||
const node = await createLibp2p({ | ||
transports: [ | ||
webSockets({ | ||
filter: filters.all, | ||
}), | ||
webRTC({}), | ||
circuitRelayTransport({ | ||
discoverRelays: 1, | ||
}), | ||
], | ||
connectionEncryption: [noise()], | ||
streamMuxers: [mplex()], | ||
}) | ||
|
||
await node.start() | ||
|
||
// handle the echo protocol | ||
await node.handle("/echo/1.0.0", ({ stream }) => { | ||
console.log("incoming stream") | ||
pipe( | ||
stream, | ||
async function* (source) { | ||
for await (const buf of source) { | ||
const incoming = toString(buf.subarray()) | ||
appendOutput(`Received message '${clean(incoming)}'`) | ||
yield buf | ||
} | ||
}, | ||
stream | ||
) | ||
}) | ||
|
||
node.peerStore.addEventListener("change:multiaddrs", (event) => { | ||
const { peerId } = event.detail | ||
|
||
if (node.getMultiaddrs().length === 0 || !node.peerId.equals(peerId)) { | ||
return | ||
} | ||
|
||
node.getMultiaddrs().forEach((ma) => { | ||
if (ma.protoCodes().includes(CIRCUIT_RELAY_CODE)) { | ||
if (ma.protos().pop()?.name === 'p2p') { | ||
ma = ma.decapsulateCode(protocols('p2p').code) | ||
} | ||
const newWebrtcDirectAddress = multiaddr(ma.toString() + '/webrtc/p2p/' + node.peerId) | ||
|
||
const webrtcAddrString = newWebrtcDirectAddress.toString() | ||
|
||
// only update if the address is new | ||
if (newWebrtcDirectAddress?.toString() !== webrtcDirectAddress?.toString()) { | ||
appendOutput(`Listening on '${webrtcAddrString}'`) | ||
sendSection.style.display = "block" | ||
webrtcDirectAddress = newWebrtcDirectAddress | ||
connected_peer.innerText = webrtcDirectAddress | ||
} | ||
} | ||
}) | ||
}) | ||
|
||
const isWebrtc = (ma) => { | ||
return ma.protoCodes().includes(WEBRTC_CODE) | ||
} | ||
|
||
window.connect.onclick = async () => { | ||
const ma = multiaddr(window.peer.value) | ||
appendOutput(`Dialing '${ma}'`) | ||
const connection = await node.dial(ma) | ||
|
||
if (!isWebrtc(ma)) { | ||
return | ||
} | ||
|
||
const outgoing_stream = await connection.newStream(["/echo/1.0.0"]) | ||
|
||
pipe(sender, outgoing_stream, async (src) => { | ||
for await (const buf of src) { | ||
const response = toString(buf.subarray()) | ||
appendOutput(`Received message '${clean(response)}'`) | ||
} | ||
}) | ||
} | ||
|
||
window.send.onclick = async () => { | ||
const message = `${window.message.value}\n` | ||
appendOutput(`Sending message '${clean(message)}'`) | ||
sender.push(fromString(message)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"name": "js-libp2p-webrtc-private-to-private", | ||
"version": "1.0.0", | ||
"description": "Connect a browser to another browser", | ||
"type": "module", | ||
"scripts": { | ||
"start": "vite", | ||
"build": "vite build", | ||
"relay": "node relay.js", | ||
"test:firefox": "npm run build && playwright test --browser=firefox tests", | ||
"test:chrome": "npm run build && playwright test tests", | ||
"test": "npm run test:firefox && npm run test:chrome" | ||
}, | ||
"dependencies": { | ||
"@chainsafe/libp2p-noise": "^11.0.0", | ||
"@libp2p/websockets": "^5.0.3", | ||
"@libp2p/mplex": "^7.0.0", | ||
"@multiformats/multiaddr": "^12.0.0", | ||
"it-pushable": "^3.1.0", | ||
"js-libp2p-webrtc": "file:../../", | ||
"libp2p": "^0.43.0", | ||
"vite": "^4.2.1" | ||
}, | ||
"devDependencies": { | ||
"@playwright/test": "^1.30.0", | ||
"test-util-ipfs-example": "^1.0.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { mplex } from "@libp2p/mplex" | ||
import { createLibp2p } from "libp2p" | ||
import { noise } from "@chainsafe/libp2p-noise" | ||
import { circuitRelayServer } from 'libp2p/circuit-relay' | ||
import { webSockets } from '@libp2p/websockets' | ||
import * as filters from '@libp2p/websockets/filters' | ||
|
||
const server = await createLibp2p({ | ||
addresses: { | ||
listen: ['/ip4/127.0.0.1/tcp/0/ws'] | ||
}, | ||
transports: [ | ||
webSockets({ | ||
filter: filters.all | ||
}), | ||
], | ||
connectionEncryption: [noise()], | ||
streamMuxers: [mplex()], | ||
relay: circuitRelayServer({}), | ||
}) | ||
|
||
console.log("p2p addr: ", server.getMultiaddrs().map((ma) => ma.toString())) |
Oops, something went wrong.