Franck Royer e6d3c2f595
Improve count of relay peers
Active relay peers are peer which are part of the gossip mesh.
Which means that it's not just a peer we are connect to but a peer on
subscribed to the same pubsub topic, with a good score, part of the
mesh, etc.

Mesh maintenance is done during the gossipsub hearbeat so it's the best
time to review the count.

A store peer is any peer we are connected to that support the store
protocol, so it can be counted when a new peer is added to the store.

This does not cater for store peers that disconnect, but we are not
handling those just yet.
2022-02-28 17:23:30 +11:00

93 lines
2.4 KiB
TypeScript

import { WakuMessage } from "js-waku";
import { ChatContentTopic } from "./App";
import ChatList from "./ChatList";
import MessageInput from "./MessageInput";
import { useWaku } from "./WakuContext";
import { TitleBar } from "@livechat/ui-kit";
import { Message } from "./Message";
import { ChatMessage } from "./chat_message";
import { useEffect, useState } from "react";
interface Props {
messages: Message[];
commandHandler: (cmd: string) => void;
nick: string;
}
export default function Room(props: Props) {
const { waku } = useWaku();
const [storePeers, setStorePeers] = useState(0);
const [relayPeers, setRelayPeers] = useState(0);
useEffect(() => {
if (!waku) return;
// Update relay peer count on heartbeat
waku.relay.on("gossipsub:heartbeat", () => {
setRelayPeers(waku.relay.getPeers().size);
});
}, [waku]);
useEffect(() => {
if (!waku) return;
// Update store peer when new peer connected & identified
waku.libp2p.peerStore.on("change:protocols", async () => {
let counter = 0;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for await (const _peer of waku.store.peers) {
counter++;
}
setStorePeers(counter);
});
}, [waku]);
return (
<div
className="chat-container"
style={{ height: "98vh", display: "flex", flexDirection: "column" }}
>
<TitleBar
leftIcons={[`Peers: ${relayPeers} relay ${storePeers} store.`]}
title="Waku v2 chat app"
/>
<ChatList messages={props.messages} />
<MessageInput
sendMessage={
waku
? async (messageToSend) => {
return handleMessage(
messageToSend,
props.nick,
props.commandHandler,
waku.relay.send.bind(waku.relay)
);
}
: undefined
}
/>
</div>
);
}
async function handleMessage(
message: string,
nick: string,
commandHandler: (cmd: string) => void,
messageSender: (msg: WakuMessage) => Promise<void>
) {
if (message.startsWith("/")) {
commandHandler(message);
} else {
const timestamp = new Date();
const chatMessage = ChatMessage.fromUtf8String(timestamp, nick, message);
const wakuMsg = await WakuMessage.fromBytes(
chatMessage.encode(),
ChatContentTopic,
{ timestamp }
);
return messageSender(wakuMsg);
}
}