Merge pull request #256 from waku-org/chore/bump-web-chat
feat(web-chat): show more details about discovered & connected peers
This commit is contained in:
commit
11eaec74cc
File diff suppressed because it is too large
Load Diff
|
@ -4,12 +4,14 @@
|
|||
"private": true,
|
||||
"homepage": "/web-chat",
|
||||
"dependencies": {
|
||||
"@multiformats/multiaddr": "11.0.7",
|
||||
"@libp2p/bootstrap": "^8.0.0",
|
||||
"@waku/react": "^0.0.4-fe5b4c4",
|
||||
"@waku/dns-discovery": "^0.0.15",
|
||||
"@waku/interfaces": "^0.0.16",
|
||||
"@waku/peer-exchange": "^0.0.14",
|
||||
"@waku/react": "0.0.3-7aeb24a",
|
||||
"@waku/sdk": "^0.0.17",
|
||||
"@waku/interfaces": "^0.0.17",
|
||||
"@waku/peer-exchange": "^0.0.15",
|
||||
"@livechat/ui-kit": "^0.5.0-24",
|
||||
"@multiformats/multiaddr": "12.1.5",
|
||||
"@waku/sdk": "^0.0.18",
|
||||
"process": "^0.11.10",
|
||||
"protons-runtime": "^3.1.0",
|
||||
"react": "^17.0.2",
|
||||
|
|
|
@ -17,8 +17,15 @@ export default function Room(props: Props) {
|
|||
const { encoder } = useContentPair();
|
||||
const { push: onPush } = useLightPush({ node, encoder });
|
||||
|
||||
const { bootstrapPeers, peerExchangePeers } = useNodePeers(node);
|
||||
const { storePeers, filterPeers, lightPushPeers } = usePeers({ node });
|
||||
const {
|
||||
connectedBootstrapPeers,
|
||||
connectedPeerExchangePeers,
|
||||
discoveredBootstrapPeers,
|
||||
discoveredPeerExchangePeers,
|
||||
} = useNodePeers(node);
|
||||
const { allConnected, storePeers, filterPeers, lightPushPeers } = usePeers({
|
||||
node,
|
||||
});
|
||||
|
||||
const onSend = async (text: string) => {
|
||||
if (!onPush || !text) {
|
||||
|
@ -40,18 +47,39 @@ export default function Room(props: Props) {
|
|||
}
|
||||
};
|
||||
|
||||
const allConnectedLength = orZero(allConnected?.length);
|
||||
const lightPushPeersLength = orZero(lightPushPeers?.length);
|
||||
const filterPeersLength = orZero(filterPeers?.length);
|
||||
const storePeersLength = orZero(storePeers?.length);
|
||||
|
||||
const peersMessage = `Peers: ${lightPushPeersLength} light push, ${filterPeersLength} filter, ${storePeersLength} store.`;
|
||||
const bootstrapPeersMessage = `Bootstrap (DNS Discovery): ${bootstrapPeers.size}, Peer exchange: ${peerExchangePeers.size}. `;
|
||||
|
||||
return (
|
||||
<div className="h-screen flex flex-col">
|
||||
<div className="flex justify-between items-center bg-gray-800 text-white p-4">
|
||||
<div>{peersMessage}</div>
|
||||
<div>{bootstrapPeersMessage} View console for more details.</div>
|
||||
<div>
|
||||
<div>Peers Connected: {allConnectedLength}</div>
|
||||
<div className="mt-2">Store: {storePeersLength}</div>
|
||||
<div>Filter: {filterPeersLength}</div>
|
||||
<div>Light Push: {lightPushPeersLength}</div>
|
||||
</div>
|
||||
<div>Waku v2 Web Chat</div>
|
||||
<div>
|
||||
<div className="mt-2">
|
||||
Peers Discovered:{" "}
|
||||
{discoveredBootstrapPeers.size + discoveredPeerExchangePeers.size}
|
||||
</div>
|
||||
<div>
|
||||
Bootstrap: {discoveredBootstrapPeers.size} Peer Exchange:{" "}
|
||||
{discoveredPeerExchangePeers.size}
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
Peers Connected:{" "}
|
||||
{connectedBootstrapPeers.size + connectedPeerExchangePeers.size}
|
||||
</div>
|
||||
<div>
|
||||
Bootstrap: {connectedBootstrapPeers.size} Peer Exchange:{" "}
|
||||
{connectedPeerExchangePeers.size}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ChatList messages={props.messages} />
|
||||
<MessageInput hasLightPushPeers={!!lightPushPeers} sendMessage={onSend} />
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { generate } from "server-name-generator";
|
||||
import { Message } from "./Message";
|
||||
import type { PeerId } from "@libp2p/interface-peer-id";
|
||||
import type { Peer } from "@libp2p/interface-peer-store";
|
||||
import type { LightNode, StoreQueryOptions, Waku } from "@waku/interfaces";
|
||||
import {
|
||||
EPeersByDiscoveryEvents,
|
||||
LightNode,
|
||||
StoreQueryOptions,
|
||||
Waku,
|
||||
Tags,
|
||||
} from "@waku/interfaces";
|
||||
import type { waku } from "@waku/sdk";
|
||||
|
||||
import { useFilterMessages, useStoreMessages } from "@waku/react";
|
||||
|
@ -59,42 +66,100 @@ export const useMessages = (params: UseMessagesParams): UseMessagesResult => {
|
|||
// can be safely ignored
|
||||
// this is for experiments on waku side around new discovery options
|
||||
export const useNodePeers = (node: undefined | LightNode) => {
|
||||
const [bootstrapPeers, setBootstrapPeers] = useState(new Set<string>());
|
||||
const [peerExchangePeers, setPeerExchangePeers] = useState(new Set<string>());
|
||||
const [discoveredBootstrapPeers, setBootstrapPeers] = useState<Set<PeerId>>(
|
||||
new Set()
|
||||
);
|
||||
const [connectedBootstrapPeers, setConnectedBootstrapPeers] = useState<
|
||||
Set<PeerId>
|
||||
>(new Set());
|
||||
const [discoveredPeerExchangePeers, setPeerExchangePeers] = useState<
|
||||
Set<PeerId>
|
||||
>(new Set());
|
||||
const [connectedPeerExchangePeers, setConnectedPeerExchangePeers] = useState<
|
||||
Set<PeerId>
|
||||
>(new Set());
|
||||
|
||||
useEffect(() => {
|
||||
if (!node) return;
|
||||
|
||||
const listener = async (evt: any) => {
|
||||
const { peerId } = evt.detail;
|
||||
const tags = Array.from(
|
||||
(await node.libp2p.peerStore.get(peerId)).tags.keys()
|
||||
);
|
||||
if (tags.includes("peer-exchange")) {
|
||||
setPeerExchangePeers((peers) => new Set(peers).add(peerId.toString()));
|
||||
} else {
|
||||
setBootstrapPeers((peers) => new Set(peers).add(peerId.toString()));
|
||||
}
|
||||
const handleDiscoveryBootstrap = (event: CustomEvent<PeerId>) => {
|
||||
setBootstrapPeers((peers) => new Set([...peers, event.detail]));
|
||||
};
|
||||
|
||||
// Update store peer when new peer connected & identified
|
||||
node.libp2p.addEventListener("peer:identify", listener);
|
||||
const handleConnectBootstrap = (event: CustomEvent<PeerId>) => {
|
||||
setConnectedBootstrapPeers((peers) => new Set([...peers, event.detail]));
|
||||
};
|
||||
|
||||
const handleDiscoveryPeerExchange = (event: CustomEvent<PeerId>) => {
|
||||
setPeerExchangePeers((peers) => new Set([...peers, event.detail]));
|
||||
};
|
||||
|
||||
const handleConnectPeerExchange = (event: CustomEvent<PeerId>) => {
|
||||
setConnectedPeerExchangePeers(
|
||||
(peers) => new Set([...peers, event.detail])
|
||||
);
|
||||
};
|
||||
|
||||
const initHookData = async () => {
|
||||
const { CONNECTED, DISCOVERED } =
|
||||
await node.connectionManager.getPeersByDiscovery();
|
||||
|
||||
setConnectedBootstrapPeers(
|
||||
new Set(CONNECTED[Tags.BOOTSTRAP].map((p) => p.id))
|
||||
);
|
||||
setConnectedPeerExchangePeers(
|
||||
new Set(CONNECTED[Tags.PEER_EXCHANGE].map((p) => p.id))
|
||||
);
|
||||
setBootstrapPeers(new Set(DISCOVERED[Tags.BOOTSTRAP].map((p) => p.id)));
|
||||
setPeerExchangePeers(
|
||||
new Set(DISCOVERED[Tags.PEER_EXCHANGE].map((p) => p.id))
|
||||
);
|
||||
|
||||
node.connectionManager.addEventListener(
|
||||
EPeersByDiscoveryEvents.PEER_DISCOVERY_BOOTSTRAP,
|
||||
handleDiscoveryBootstrap
|
||||
);
|
||||
node.connectionManager.addEventListener(
|
||||
EPeersByDiscoveryEvents.PEER_CONNECT_BOOTSTRAP,
|
||||
handleConnectBootstrap
|
||||
);
|
||||
node.connectionManager.addEventListener(
|
||||
EPeersByDiscoveryEvents.PEER_DISCOVERY_PEER_EXCHANGE,
|
||||
handleDiscoveryPeerExchange
|
||||
);
|
||||
node.connectionManager.addEventListener(
|
||||
EPeersByDiscoveryEvents.PEER_CONNECT_PEER_EXCHANGE,
|
||||
handleConnectPeerExchange
|
||||
);
|
||||
};
|
||||
|
||||
initHookData();
|
||||
|
||||
return () => {
|
||||
node.libp2p.removeEventListener("peer:identify", listener);
|
||||
node.connectionManager.removeEventListener(
|
||||
EPeersByDiscoveryEvents.PEER_DISCOVERY_BOOTSTRAP,
|
||||
handleDiscoveryBootstrap
|
||||
);
|
||||
node.connectionManager.removeEventListener(
|
||||
EPeersByDiscoveryEvents.PEER_CONNECT_BOOTSTRAP,
|
||||
handleConnectBootstrap
|
||||
);
|
||||
node.connectionManager.removeEventListener(
|
||||
EPeersByDiscoveryEvents.PEER_DISCOVERY_PEER_EXCHANGE,
|
||||
handleDiscoveryPeerExchange
|
||||
);
|
||||
node.connectionManager.removeEventListener(
|
||||
EPeersByDiscoveryEvents.PEER_CONNECT_PEER_EXCHANGE,
|
||||
handleConnectPeerExchange
|
||||
);
|
||||
};
|
||||
}, [node]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Bootstrap Peers:");
|
||||
console.table(bootstrapPeers);
|
||||
|
||||
console.log("Peer Exchange Peers:");
|
||||
console.table(peerExchangePeers);
|
||||
}, [bootstrapPeers, peerExchangePeers]);
|
||||
|
||||
return {
|
||||
bootstrapPeers,
|
||||
peerExchangePeers,
|
||||
discoveredBootstrapPeers,
|
||||
connectedBootstrapPeers,
|
||||
discoveredPeerExchangePeers,
|
||||
connectedPeerExchangePeers,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -103,9 +168,10 @@ type UsePeersParams = {
|
|||
};
|
||||
|
||||
type UsePeersResults = {
|
||||
storePeers?: undefined | Peer[];
|
||||
filterPeers?: undefined | Peer[];
|
||||
lightPushPeers?: undefined | Peer[];
|
||||
allConnected?: PeerId[];
|
||||
storePeers?: PeerId[];
|
||||
filterPeers?: PeerId[];
|
||||
lightPushPeers?: PeerId[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -120,22 +186,24 @@ export const usePeers = (params: UsePeersParams): UsePeersResults => {
|
|||
const { node } = params;
|
||||
const [peers, setPeers] = React.useState<UsePeersResults>({});
|
||||
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
const listener = async (_event?: any) => {
|
||||
const listener = async () => {
|
||||
const peers = await Promise.all([
|
||||
node?.libp2p.getConnections().map((c) => c.remotePeer),
|
||||
handleCatch(node?.store?.peers()),
|
||||
handleCatch(node?.filter?.peers()),
|
||||
handleCatch(node?.lightPush?.peers()),
|
||||
]);
|
||||
|
||||
setPeers({
|
||||
storePeers: peers[0],
|
||||
filterPeers: peers[1],
|
||||
lightPushPeers: peers[2],
|
||||
allConnected: peers[0],
|
||||
storePeers: peers[1]?.map((p) => p.id),
|
||||
filterPeers: peers[2]?.map((p) => p.id),
|
||||
lightPushPeers: peers[3]?.map((p) => p.id),
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { CONTENT_TOPIC, PROTOCOLS } from "./config";
|
|||
const NODE_OPTIONS = {
|
||||
libp2p: {
|
||||
peerDiscovery: [
|
||||
wakuDnsDiscovery([enrTree.TEST], {
|
||||
wakuDnsDiscovery([enrTree.PROD], {
|
||||
store: 1,
|
||||
filter: 2,
|
||||
lightPush: 2,
|
||||
|
|
Loading…
Reference in New Issue