2
2
3
3
const debug = require ( 'debug' )
4
4
const log = debug ( 'libp2p:webrtc-star' )
5
+
5
6
const multiaddr = require ( 'multiaddr' )
6
7
const mafmt = require ( 'mafmt' )
8
+ const Id = require ( 'peer-id' )
9
+
7
10
const withIs = require ( 'class-is' )
8
- const io = require ( 'socket.io-client' )
9
11
const EE = require ( 'events' ) . EventEmitter
12
+ const assert = require ( 'assert' )
13
+
10
14
const SimplePeer = require ( 'simple-peer' )
11
- const PeerId = require ( 'peer-id ' )
12
- const PeerInfo = require ( 'peer-info' )
15
+ const webrtcSupport = require ( 'webrtcsupport ' )
16
+
13
17
const Connection = require ( 'interface-connection' ) . Connection
14
18
const toPull = require ( 'stream-to-pull-stream' )
15
- const once = require ( 'once' )
16
- const setImmediate = require ( 'async/setImmediate' )
17
- const webrtcSupport = require ( 'webrtcsupport' )
18
- const utils = require ( './utils' )
19
- const cleanUrlSIO = utils . cleanUrlSIO
20
- const cleanMultiaddr = utils . cleanMultiaddr
21
19
20
+ const setImmediate = require ( 'async/setImmediate' )
21
+ const once = require ( 'once' )
22
22
const noop = once ( ( ) => { } )
23
23
24
- const sioOptions = {
25
- transports : [ 'websocket' ] ,
26
- 'force new connection' : true
27
- }
28
-
29
24
class WebRTCStar {
30
25
constructor ( options ) {
31
26
options = options || { }
32
27
33
- this . maSelf = undefined
34
-
35
- this . sioOptions = {
36
- transports : [ 'websocket' ] ,
37
- 'force new connection' : true
38
- }
39
-
40
28
if ( options . wrtc ) {
41
29
this . wrtc = options . wrtc
42
30
}
43
31
44
- this . discovery = new EE ( )
45
- this . discovery . tag = 'webRTCStar'
46
- this . discovery . start = ( callback ) => { setImmediate ( callback ) }
47
- this . discovery . stop = ( callback ) => { setImmediate ( callback ) }
48
-
49
- this . listenersRefs = { }
50
- this . _peerDiscovered = this . _peerDiscovered . bind ( this )
32
+ assert ( options . exchange , 'Exchange missing!' )
33
+ this . exchange = options . exchange
51
34
}
52
35
53
36
dial ( ma , options , callback ) {
@@ -58,10 +41,9 @@ class WebRTCStar {
58
41
59
42
callback = callback ? once ( callback ) : noop
60
43
61
- const intentId = ( ~ ~ ( Math . random ( ) * 1e9 ) ) . toString ( 36 ) + Date . now ( )
44
+ let b58 = ma . toString ( ) . split ( 'ipfs/' ) . pop ( )
62
45
63
- const sioClient = this
64
- . listenersRefs [ Object . keys ( this . listenersRefs ) [ 0 ] ] . io
46
+ log ( 'dialing %s %s' , ma , b58 )
65
47
66
48
const spOptions = { initiator : true , trickle : false }
67
49
@@ -74,43 +56,41 @@ class WebRTCStar {
74
56
let connected = false
75
57
76
58
channel . on ( 'signal' , ( signal ) => {
77
- sioClient . emit ( 'ss-handshake' , {
78
- intentId : intentId ,
79
- srcMultiaddr : this . maSelf . toString ( ) ,
80
- dstMultiaddr : ma . toString ( ) ,
81
- signal : signal
82
- } )
83
- } )
84
-
85
- channel . once ( 'timeout' , ( ) => callback ( new Error ( 'timeout' ) ) )
86
-
87
- channel . once ( 'error' , ( err ) => {
88
- if ( ! connected ) { callback ( err ) }
89
- } )
59
+ log ( 'dial#%s got signal' , ma )
60
+ this . exchange . request ( Id . createFromB58String ( b58 ) , 'webrtc' , Buffer . from ( JSON . stringify ( { signal, ma : '/ip4/0.0.0.0/tcp/127.0.0.1' } ) ) , ( err , result ) => { // TODO: fix this
61
+ if ( err ) {
62
+ log ( 'dial#%s exchange failed %s' , ma , err )
63
+ return callback ( err )
64
+ }
90
65
91
- // NOTE: aegir segfaults if we do .once on the socket.io event emitter and we
92
- // are clueless as to why.
93
- sioClient . on ( 'ws-handshake' , ( offer ) => {
94
- if ( offer . intentId === intentId && offer . err ) {
95
- return callback ( new Error ( offer . err ) )
96
- }
66
+ let offer
67
+ try {
68
+ offer = JSON . parse ( String ( result ) )
69
+ } catch ( err ) {
70
+ log ( 'dial#%s malformed response %s' , ma , err )
71
+ return callback ( err )
72
+ }
97
73
98
- if ( offer . intentId !== intentId || ! offer . answer ) {
99
- return
100
- }
74
+ channel . once ( 'connect' , ( ) => {
75
+ log ( 'dial#%s connected' , ma )
76
+ connected = true
77
+ conn . destroy = channel . destroy . bind ( channel )
101
78
102
- channel . once ( 'connect' , ( ) => {
103
- connected = true
104
- conn . destroy = channel . destroy . bind ( channel )
79
+ channel . once ( 'close' , ( ) => conn . destroy ( ) )
105
80
106
- channel . once ( 'close' , ( ) => conn . destroy ( ) )
81
+ conn . getObservedAddrs = ( callback ) => callback ( null , [ ma ] )
107
82
108
- conn . getObservedAddrs = ( callback ) => callback ( null , [ ma ] )
83
+ callback ( null , conn )
84
+ } )
109
85
110
- callback ( null , conn )
86
+ channel . signal ( offer . signal )
111
87
} )
88
+ } )
112
89
113
- channel . signal ( offer . signal )
90
+ channel . once ( 'timeout' , ( ) => callback ( new Error ( 'timeout' ) ) )
91
+
92
+ channel . once ( 'error' , ( err ) => {
93
+ if ( ! connected ) { callback ( err ) }
114
94
} )
115
95
116
96
return conn
@@ -131,36 +111,19 @@ class WebRTCStar {
131
111
return setImmediate ( ( ) => callback ( new Error ( 'no WebRTC support' ) ) )
132
112
}
133
113
134
- this . maSelf = ma
114
+ log ( 'listening on %s' , ma )
135
115
136
- const sioUrl = cleanUrlSIO ( ma )
116
+ let ns = listener . ns = 'webrtc' // TODO: should this be ma.toString() ?
117
+ listener . ma = ma
137
118
138
- log ( 'Dialing to Signalling Server on: ' + sioUrl )
139
-
140
- listener . io = io . connect ( sioUrl , sioOptions )
141
-
142
- listener . io . once ( 'connect_error' , callback )
143
- listener . io . once ( 'error' , ( err ) => {
144
- listener . emit ( 'error' , err )
145
- listener . emit ( 'close' )
146
- } )
119
+ this . exchange . listen ( ns , ( request , cb ) => {
120
+ let offer
147
121
148
- listener . io . on ( 'ws-handshake' , incommingDial )
149
- listener . io . on ( 'ws-peer' , this . _peerDiscovered )
150
-
151
- listener . io . on ( 'connect' , ( ) => {
152
- listener . io . emit ( 'ss-join' , ma . toString ( ) )
153
- } )
154
-
155
- listener . io . once ( 'connect' , ( ) => {
156
- listener . emit ( 'listening' )
157
- callback ( )
158
- } )
159
-
160
- const self = this
161
- function incommingDial ( offer ) {
162
- if ( offer . answer || offer . err ) {
163
- return
122
+ try {
123
+ offer = JSON . parse ( String ( request ) )
124
+ } catch ( err ) {
125
+ log ( 'got malformed offer' , err )
126
+ return cb ( err )
164
127
}
165
128
166
129
const spOptions = { trickle : false }
@@ -173,40 +136,37 @@ class WebRTCStar {
173
136
const conn = new Connection ( toPull . duplex ( channel ) )
174
137
175
138
channel . once ( 'connect' , ( ) => {
139
+ log ( 'connected' )
140
+
176
141
conn . getObservedAddrs = ( callback ) => {
177
- return callback ( null , [ offer . srcMultiaddr ] )
142
+ return callback ( null , [ multiaddr ( offer . ma ) ] ) // TODO: this isn't really safe AT ALL...
178
143
}
179
144
180
145
listener . emit ( 'connection' , conn )
181
146
handler ( conn )
182
147
} )
183
148
184
149
channel . once ( 'signal' , ( signal ) => {
185
- offer . signal = signal
186
- offer . answer = true
187
- listener . io . emit ( 'ss-handshake' , offer )
150
+ log ( 'sending back signal' )
151
+ cb ( null , Buffer . from ( JSON . stringify ( { signal, ma : listener . ma . toString ( ) } ) ) )
188
152
} )
189
153
190
154
channel . signal ( offer . signal )
191
- }
155
+ } )
192
156
}
193
157
194
158
listener . close = ( callback ) => {
195
159
callback = callback ? once ( callback ) : noop
196
160
197
- listener . io . emit ( 'ss-leave' )
161
+ this . exchange . unhandle ( listener . ns )
198
162
199
- setImmediate ( ( ) => {
200
- listener . emit ( 'close' )
201
- callback ( )
202
- } )
163
+ setImmediate ( callback )
203
164
}
204
165
205
166
listener . getAddrs = ( callback ) => {
206
- setImmediate ( ( ) => callback ( null , [ this . maSelf ] ) )
167
+ setImmediate ( ( ) => callback ( null , listener . ma ? [ listener . ma ] : [ ] ) )
207
168
}
208
169
209
- this . listenersRefs [ multiaddr . toString ( ) ] = listener
210
170
return listener
211
171
}
212
172
@@ -223,18 +183,6 @@ class WebRTCStar {
223
183
return mafmt . WebRTCStar . matches ( ma )
224
184
} )
225
185
}
226
-
227
- _peerDiscovered ( maStr ) {
228
- log ( 'Peer Discovered:' , maStr )
229
- maStr = cleanMultiaddr ( maStr )
230
-
231
- const split = maStr . split ( '/ipfs/' )
232
- const peerIdStr = split [ split . length - 1 ]
233
- const peerId = PeerId . createFromB58String ( peerIdStr )
234
- const peerInfo = new PeerInfo ( peerId )
235
- peerInfo . multiaddrs . add ( multiaddr ( maStr ) )
236
- this . discovery . emit ( 'peer' , peerInfo )
237
- }
238
186
}
239
187
240
188
module . exports = withIs ( WebRTCStar , { className : 'WebRTCStar' , symbolName : '@libp2p/js-libp2p-webrtc-star/webrtcstar' } )
0 commit comments