@@ -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 = `debug-connection-${ device . deviceInfo . identifier } -${ appId } .lock` ;
94
96
const cacheKey = `${ device . deviceInfo . identifier } -${ appId } ` ;
95
97
const existingServer = this . deviceWebServers [ cacheKey ] ;
96
98
if ( existingServer ) {
@@ -107,22 +109,37 @@ 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 ) {
122
138
err . deviceIdentifier = device . deviceInfo . identifier ;
123
139
this . $logger . trace ( err ) ;
124
140
this . emit ( CONNECTION_ERROR_EVENT_NAME , err ) ;
125
141
acceptHandshake = false ;
142
+ this . $lockService . unlock ( clientConnectionLockFile ) ;
126
143
this . $logger . warn ( `Cannot connect to device socket. The error message is '${ err . message } '.` ) ;
127
144
}
128
145
@@ -131,6 +148,7 @@ export class AppDebugSocketProxyFactory extends EventEmitter implements IAppDebu
131
148
} ) ;
132
149
this . deviceWebServers [ cacheKey ] = server ;
133
150
server . on ( "connection" , ( webSocket , req ) => {
151
+ currentWebSocket = webSocket ;
134
152
const encoding = "utf16le" ;
135
153
136
154
const appDebugSocket : net . Socket = ( < any > req ) [ "__deviceSocket" ] ;
@@ -163,20 +181,23 @@ export class AppDebugSocketProxyFactory extends EventEmitter implements IAppDebu
163
181
} ) ;
164
182
165
183
appDebugSocket . on ( "close" , ( ) => {
184
+ currentAppSocket = null ;
166
185
this . $logger . info ( "Backend socket closed!" ) ;
167
186
webSocket . close ( ) ;
168
187
} ) ;
169
188
170
- webSocket . on ( "close" , ( ) => {
189
+ webSocket . on ( "close" , async ( ) => {
190
+ currentWebSocket = null ;
171
191
this . $logger . info ( 'Frontend socket closed!' ) ;
172
192
appDebugSocket . unpipe ( packets ) ;
173
193
packets . destroy ( ) ;
174
- device . destroyDebugSocket ( appId ) ;
194
+ await device . destroyDebugSocket ( appId ) ;
175
195
if ( ! this . $options . watch ) {
176
196
process . exit ( 0 ) ;
177
197
}
178
198
} ) ;
179
199
200
+ this . $lockService . unlock ( clientConnectionLockFile ) ;
180
201
} ) ;
181
202
182
203
return server ;
0 commit comments