@@ -11,6 +11,7 @@ export class AppDebugSocketProxyFactory extends EventEmitter implements IAppDebu
11
11
12
12
constructor ( private $logger : ILogger ,
13
13
private $errors : IErrors ,
14
+ private $lockService : ILockService ,
14
15
private $options : IOptions ,
15
16
private $net : INet ) {
16
17
super ( ) ;
@@ -54,9 +55,9 @@ export class AppDebugSocketProxyFactory extends EventEmitter implements IAppDebu
54
55
}
55
56
} ) ;
56
57
57
- frontendSocket . on ( "close" , ( ) => {
58
+ frontendSocket . on ( "close" , async ( ) => {
58
59
this . $logger . info ( "Frontend socket closed" ) ;
59
- device . destroyDebugSocket ( appId ) ;
60
+ await device . destroyDebugSocket ( appId ) ;
60
61
} ) ;
61
62
62
63
appDebugSocket . on ( "close" , ( ) => {
@@ -91,6 +92,7 @@ export class AppDebugSocketProxyFactory extends EventEmitter implements IAppDebu
91
92
}
92
93
93
94
private async addWebSocketProxy ( device : Mobile . IiOSDevice , appId : string , projectName : string ) : Promise < ws . Server > {
95
+ const clientConnectionLockFile = "web-client-connecting-for-debugging.lock" ;
94
96
const cacheKey = `${ device . deviceInfo . identifier } -${ appId } ` ;
95
97
const existingServer = this . deviceWebServers [ cacheKey ] ;
96
98
if ( existingServer ) {
@@ -107,15 +109,29 @@ export class AppDebugSocketProxyFactory extends EventEmitter implements IAppDebu
107
109
// We store the socket that connects us to the device in the upgrade request object itself and later on retrieve it
108
110
// in the connection callback.
109
111
112
+ let currentAppSocket : net . Socket = null ;
113
+ let currentWebSocket : ws = null ;
110
114
const server = new ws . Server ( < any > {
111
115
port : localPort ,
112
116
host : "localhost" ,
113
117
verifyClient : async ( info : any , callback : ( res : boolean , code ?: number , message ?: string ) => void ) => {
118
+ await this . $lockService . lock ( clientConnectionLockFile ) ;
114
119
let acceptHandshake = true ;
115
120
this . $logger . info ( "Frontend client connected." ) ;
116
121
let appDebugSocket ;
117
122
try {
123
+ if ( currentAppSocket ) {
124
+ currentAppSocket . removeAllListeners ( ) ;
125
+ currentAppSocket = null ;
126
+ if ( currentWebSocket ) {
127
+ currentWebSocket . removeAllListeners ( ) ;
128
+ currentWebSocket . close ( ) ;
129
+ currentWebSocket = null ;
130
+ }
131
+ await device . destroyDebugSocket ( appId ) ;
132
+ }
118
133
appDebugSocket = await device . getDebugSocket ( appId , projectName ) ;
134
+ currentAppSocket = appDebugSocket ;
119
135
this . $logger . info ( "Backend socket created." ) ;
120
136
info . req [ "__deviceSocket" ] = appDebugSocket ;
121
137
} catch ( err ) {
@@ -131,6 +147,7 @@ export class AppDebugSocketProxyFactory extends EventEmitter implements IAppDebu
131
147
} ) ;
132
148
this . deviceWebServers [ cacheKey ] = server ;
133
149
server . on ( "connection" , ( webSocket , req ) => {
150
+ currentWebSocket = webSocket ;
134
151
const encoding = "utf16le" ;
135
152
136
153
const appDebugSocket : net . Socket = ( < any > req ) [ "__deviceSocket" ] ;
@@ -167,16 +184,17 @@ export class AppDebugSocketProxyFactory extends EventEmitter implements IAppDebu
167
184
webSocket . close ( ) ;
168
185
} ) ;
169
186
170
- webSocket . on ( "close" , ( ) => {
187
+ webSocket . on ( "close" , async ( ) => {
171
188
this . $logger . info ( 'Frontend socket closed!' ) ;
172
189
appDebugSocket . unpipe ( packets ) ;
173
190
packets . destroy ( ) ;
174
- device . destroyDebugSocket ( appId ) ;
191
+ await device . destroyDebugSocket ( appId ) ;
175
192
if ( ! this . $options . watch ) {
176
193
process . exit ( 0 ) ;
177
194
}
178
195
} ) ;
179
196
197
+ this . $lockService . unlock ( clientConnectionLockFile ) ;
180
198
} ) ;
181
199
182
200
return server ;
0 commit comments