Skip to content

Commit f6a399d

Browse files
authored
add disconnect button (#137)
* feat: create circuit relay reservations on bootstrappers * feat: persistent peer id in js-peer * fix: pass relay listen addrs to libp2p * Revert "feat: persistent peer id in js-peer" Turns out this is a bad idea in a browser that can have multiple tabs open and you don't want them to share the same peer ID This reverts commit 50175a2. * fix: import missing type * chore: clean up bootstrap connection code * fix: allow zero connections avoid libp2p trying to establish connections automatically after disconnecting * feat: add disconnect button to peers --------- Co-authored-by: Daniel N <[email protected]>
1 parent eef2cf4 commit f6a399d

File tree

3 files changed

+35
-39
lines changed

3 files changed

+35
-39
lines changed

js-peer/src/context/ctx.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { startLibp2p } from '../lib/libp2p'
1111
import { ChatProvider } from './chat-ctx'
1212
import { PeerProvider } from './peer-ctx'
1313
import { ListenAddressesProvider } from './listen-addresses-ctx'
14-
import { PubSub, } from '@libp2p/interface'
14+
import { PubSub } from '@libp2p/interface'
1515
import { Identify } from '@libp2p/identify'
1616

1717
// 👇 The context type will be avilable "anywhere" in the app

js-peer/src/lib/libp2p.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export async function startLibp2p() {
6363
],
6464
connectionManager: {
6565
maxConnections: 10,
66-
minConnections: 3,
66+
minConnections: 0,
6767
},
6868
connectionEncryption: [noise()],
6969
streamMuxers: [yamux()],

js-peer/src/pages/index.tsx

+33-37
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { CheckCircleIcon, XCircleIcon } from '@heroicons/react/20/solid'
33
import Nav from '@/components/nav'
44
import { useLibp2pContext } from '@/context/ctx'
55
import type { Connection } from '@libp2p/interface'
6+
import { PeerId } from '@libp2p/interface'
67
import { usePeerContext } from '../context/peer-ctx'
78
import { useCallback, useEffect, useState } from 'react'
89
import Image from 'next/image'
@@ -25,7 +26,7 @@ export default function Home() {
2526

2627
setPeerStats({
2728
...peerStats,
28-
peerIds: connections.map(conn => conn.remotePeer),
29+
peerIds: connections.map((conn) => conn.remotePeer),
2930
connections: connections,
3031
connected: connections.length > 0,
3132
})
@@ -42,7 +43,7 @@ export default function Home() {
4243

4344
setListenAddresses({
4445
...listenAddresses,
45-
multiaddrs
46+
multiaddrs,
4647
})
4748
}, 1000)
4849

@@ -52,24 +53,23 @@ export default function Home() {
5253
}, [libp2p, listenAddresses, setListenAddresses])
5354

5455
type PeerProtoTuple = {
55-
peerId: string
56+
peerId: PeerId
5657
protocols: string[]
5758
}
5859

5960
const getFormattedConnections = (connections: Connection[]): PeerProtoTuple[] => {
60-
const protoNames: Map<string, string[]> = new Map()
61+
const protoNames: Map<PeerId, string[]> = new Map()
6162

6263
connections.forEach((conn) => {
63-
const exists = protoNames.get(conn.remotePeer.toString())
64+
const exists = protoNames.get(conn.remotePeer)
6465
const dedupedProtonames = [...new Set(conn.remoteAddr.protoNames())]
6566

6667
if (exists?.length) {
6768
const namesToAdd = dedupedProtonames.filter((name) => !exists.includes(name))
6869
// console.log('namesToAdd: ', namesToAdd)
69-
protoNames.set(conn.remotePeer.toString(), [...exists, ...namesToAdd])
70-
70+
protoNames.set(conn.remotePeer, [...exists, ...namesToAdd])
7171
} else {
72-
protoNames.set(conn.remotePeer.toString(), dedupedProtonames)
72+
protoNames.set(conn.remotePeer, dedupedProtonames)
7373
}
7474
})
7575

@@ -113,6 +113,10 @@ export default function Home() {
113113
[setMultiaddr],
114114
)
115115

116+
const handleDisconnectPeer = useCallback((peerId: PeerId) => {
117+
libp2p.hangUp(peerId)
118+
}, [libp2p])
119+
116120
return (
117121
<>
118122
<Head>
@@ -128,12 +132,7 @@ export default function Home() {
128132
<div className="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
129133
<h1 className="text-3xl font-bold leading-tight tracking-tight text-gray-900 flex flex-row">
130134
<p className="mr-4">Universal Connectivity</p>
131-
<Image
132-
src="/libp2p-hero.svg"
133-
alt="libp2p logo"
134-
height="46"
135-
width="46"
136-
/>
135+
<Image src="/libp2p-hero.svg" alt="libp2p logo" height="46" width="46" />
137136
</h1>
138137
</div>
139138
</header>
@@ -144,19 +143,12 @@ export default function Home() {
144143
</ul>
145144
Addresses:
146145
<ul className="my-2 space-y-2 break-all">
147-
{
148-
listenAddresses.multiaddrs.map((ma, index) => {
149-
return (
150-
<li key={`ma-${index}`}>{ma.toString()}</li>
151-
)
152-
})
153-
}
146+
{listenAddresses.multiaddrs.map((ma, index) => {
147+
return <li key={`ma-${index}`}>{ma.toString()}</li>
148+
})}
154149
</ul>
155150
<div className="my-6 w-1/2">
156-
<label
157-
htmlFor="peer-id"
158-
className="block text-sm font-medium leading-6 text-gray-900"
159-
>
151+
<label htmlFor="peer-id" className="block text-sm font-medium leading-6 text-gray-900">
160152
multiaddr to connect to
161153
</label>
162154
<div className="mt-2">
@@ -173,16 +165,17 @@ export default function Home() {
173165
</div>
174166
<button
175167
type="button"
176-
className={"rounded-md bg-indigo-600 my-2 py-2 px-3 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" + (dialling ? ' cursor-not-allowed' : '')}
168+
className={
169+
'rounded-md bg-indigo-600 my-2 py-2 px-3 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600' +
170+
(dialling ? ' cursor-not-allowed' : '')
171+
}
177172
onClick={handleConnectToMultiaddr}
178173
disabled={dialling}
179174
>
180-
{dialling && <Spinner />}{' '}
181-
Connect{dialling && 'ing'} to multiaddr
175+
{dialling && <Spinner />} Connect{dialling && 'ing'} to multiaddr
182176
</button>
183177
{err && <p className="text-red-500">{err}</p>}
184178
</div>
185-
186179
<div className="my-4 inline-flex items-center text-xl">
187180
Connected:{' '}
188181
{peerStats.connected ? (
@@ -198,14 +191,17 @@ export default function Home() {
198191
{' '}
199192
Connected peers ({getFormattedConnections(peerStats.connections).length}) 👇
200193
</h3>
201-
<pre className="px-2">
202-
{getFormattedConnections(peerStats.connections)
203-
.map(
204-
(pair) =>
205-
`${pair.peerId} (${pair.protocols.join(', ')})`,
206-
)
207-
.join('\n')}
208-
</pre>
194+
195+
<ul className="divide-y divide-gray-100">
196+
{getFormattedConnections(peerStats.connections).map((pair) => (
197+
<li key={pair.peerId.toString()} className="py-1 flex justify-between items-center">
198+
<span>{`${pair.peerId} (${pair.protocols.join(', ')})`}</span>
199+
<button onClick={() => handleDisconnectPeer(pair.peerId)} className="bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded flex flex-row">
200+
<XCircleIcon className="w-6 h-6" /> Disconnect
201+
</button>
202+
</li>
203+
))}
204+
</ul>
209205
</>
210206
) : null}
211207
</div>

0 commit comments

Comments
 (0)