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

feat: add direct relay-rtc example #260

Merged
merged 8 commits into from
Oct 2, 2023
Merged

feat: add direct relay-rtc example #260

merged 8 commits into from
Oct 2, 2023

Conversation

weboko
Copy link
Contributor

@weboko weboko commented Aug 7, 2023

A new example here is a showcase of how a client that has only WebRTC connection can communicate with a third client through an intermediary by using Waku Relay.

sequenceDiagram
    participant Alice
    participant Bob
    participant Eve
    participant Relay Node
    Alice->>Relay Node: Dial
    Bob->>Relay Node: Dial
    Eve->>Relay Node: Dial
    Alice->>Bob: Dial WebRTC
    Bob->>Alice: Add to mesh
    Alice->>Relay Node: Disconnect
    Alice->>Bob: Send message
    Bob->>Relay Node: Relay message
    Relay Node->>Eve: Relay message
Loading

Such an approach enables us to:

  • rely less on the service nodes;
  • decrease load within on the network;

@danisharora099
Copy link
Contributor

danisharora099 commented Aug 7, 2023

I'm aware it's just a draft PR but came in to say it's probably best to use a framework for better readability moving forward
Manipulating HTML from a different JS file seems quite unreadable and janky

Excited for the progress on this one!

c.remotePeer.toString()
);
const isWebRTCOutbound =
outboundStream.rawStream.constructor.name === "WebRTCStream";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaik this is the only way to know what type of stream is established in the mesh

examples/relay-chat/index.js Outdated Show resolved Hide resolved
}

node.relay.gossipSub.streamsOutbound.delete(c.remotePeer.toString());
await node.relay.gossipSub.createOutboundStream(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the main problem with the current approach, due to how WebRTC transport is made it is able only to create outbound connection using WebRTCStream but inbound stays MplexStream which is wrong, and prevents the mesh from functioning over WebRTC transport.

Anyway we don't intend to limit ourselves to the libp2p's WebRTC transport and we need a different solution on which I am working: it is to establish WebRTC connection similarly to how we do it in noise-rtc by using contentTopics. Main thing that makes everything ugly here is to manually put streams and connections into gossipSub

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but inbound stays MplexStream which is wrong, and prevents the mesh from functioning over WebRTC transport.

Is that a libp2p bug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say it is gossipSub's bug since it is failing to upgrade inbound connection from mplex to webrtc due to the condition explicitly skipping it and it happens to be that webrtc transport starts as mplex and then get's upgraded

I am looking at how to fix it in js-libp2p-gossipsub but I consider it to be a low-priority

@weboko weboko marked this pull request as ready for review August 29, 2023 23:32
@weboko weboko requested a review from a team as a code owner August 29, 2023 23:32
@weboko
Copy link
Contributor Author

weboko commented Aug 29, 2023

For this one, I intentionally used chat template that we have since it is pretty straightforward but let's discuss how it can be improved so we can have event better WoW effect for the next example I am preparing

I'm aware it's just a draft PR but came in to say it's probably best to use a framework for better readability moving forward Manipulating HTML from a different JS file seems quite unreadable and janky

examples/relay-chat/README.md Outdated Show resolved Hide resolved
<div>
<input
id="remoteNode"
value="/dns4/node-01.ac-cn-hongkong-c.go-waku.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm1fVVprL9EaDpDw4frNX3CPfZu5cBqhtk9Ncm6WCvprpv"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah so actually we may not need to run our own go-waku node, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the main criteria is to have circuit-relay implemented on nodes and as of now it only works with go-waku nodes in prod fleet, the guide is to make sure folks know what to do in case it does not work due to low capacity or something

}

node.relay.gossipSub.streamsOutbound.delete(c.remotePeer.toString());
await node.relay.gossipSub.createOutboundStream(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but inbound stays MplexStream which is wrong, and prevents the mesh from functioning over WebRTC transport.

Is that a libp2p bug?

examples/relay-chat/index.js Outdated Show resolved Hide resolved
@weboko weboko requested a review from fryorcraken August 31, 2023 16:01
@danisharora099
Copy link
Contributor

danisharora099 commented Sep 5, 2023

general comment: can we add details of this works in the description/README? there is mention of how to start and navigate the example, but we should add what is happening with this example theoretically:

  • how it's different from using relay directly
  • what use cases could benefit with using WebRTC + relay
  • whatever else you feel is relevant for theoretical understanding

This would also help with the review process :D

Copy link
Collaborator

@fryorcraken fryorcraken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that you can use mermaidsyntax in GitHub comments/description for sequence diagram. Maybe would be better to have Alice, Bob, Carol in the diagram than tab#N.

@@ -20,6 +20,7 @@ jobs:
web-chat,
noise-js,
noise-rtc,
relay-direct-chat
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, maybe relay-webrtc would be a better name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I named it like this first but I hope to push for the second example with gossiping discovery and call it relay-webrtc

Copy link
Contributor

@danisharora099 danisharora099 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for this effort!

did a first review

general comment: code feels hard to read and like a challenge to maintain. imo readability is of bigger importance considering this is an example for end users.
i would incline to refactor it for the following:

  • break down initWakuContext into functions like setupMessageHandlers, configureWaku, etc
  • functions like initUI mix both UI initialisation and event handling -- consider separating them
  • we could also go ahead and group similar functionalities together:
    • functions related to message handling can be together, UI related can be together, etc
  • modularising the code: breaking down components into modules like ui.js, waku.js, etc
  • adding some comments/docs on functions that might be hard to understand for the user at first like setRelayMeshInfo, dropNetworkConnections, dialWebRTCpeer, onExit

cc @LordGhostX how do you feel?

const multiaddr = webrtcPeer.value;

if (!multiaddr) {
throw Error("No multiaddr to dial webrtc");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the input box is empty, we should prompt the user to enter a multiaddr instead of throwing

Comment on lines 46 to 51
ui.onExit(async () => {
ui.setStatus("disconnecting...", "progress");
await unsubscribeFromMessages();
ui.setStatus("disconnected", "terminated");
ui.resetMessages();
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

during this, let's also make sure to clear attached event listeners to avoid potential memory leaks

examples/relay-direct-chat/index.js Outdated Show resolved Hide resolved
});
}

async function initWakuContext({ ui, contentTopic }) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be a fairly long function (150 lines); it would help to break it down into multiple functions

also might help keep code more maintainable & readable to break off code/functions into multiple files

}

// UI adapter
function initUI() {
Copy link
Contributor

@danisharora099 danisharora099 Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will help to encapsulate this function into a separate file/UI class for better readability & maintainability

@fryorcraken
Copy link
Collaborator

this is an example for end users.

I disagree there @danisharora099 . This is a PoC to demonstrate possible usage of WebRTC for Waku Relay. Should we just have a different repo for PoCs?

@danisharora099
Copy link
Contributor

I disagree there @danisharora099 . This is a PoC to demonstrate possible usage of WebRTC for Waku Relay. Should we just have a different repo for PoCs?

I incline towards aiming to have our POCs as readable as our examples as it doesn't take much from our side; and can serve similar purposes

@vpavlin
Copy link
Member

vpavlin commented Sep 21, 2023

Why not just move the PoCs to a different folder and then have them as poc.waku.org instead of examples.waku.org ?

Then they are all in the same repo, but it is clear(er) that they may not be fully fledged examples to use for your app

@weboko
Copy link
Contributor Author

weboko commented Sep 26, 2023

As discussed last week - the following improvement will be introduced in root template here #271

As for if we need to split PoC and exmapels I think it's not needed yet.
Right now all of examples are PoCs for me.
Later when we have exampels as sets of defined patterns that devs are interested in - would be good to split.

@fryorcraken
Copy link
Collaborator

Why not just move the PoCs to a different folder and then have them as poc.waku.org instead of examples.waku.org ?

Then they are all in the same repo, but it is clear(er) that they may not be fully fledged examples to use for your app

FYI, Comms Hubs was keen on the usage of lab.waku.org.

@weboko
Copy link
Contributor Author

weboko commented Sep 27, 2023

Decoupled this conv to separate issue #275

@weboko weboko merged commit 1bd7597 into master Oct 2, 2023
9 checks passed
@weboko weboko deleted the weboko/relay-rtc branch October 2, 2023 23:03
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

Successfully merging this pull request may close these issues.

5 participants