Dopo un endpoint ha sia inviato e ricevuto un primo frame di controllo, che endpoint DEVE chiudere la connessione WebSocket come definito nella sezione 7.1.1. (RFC 6455 7.1.2)
L'istanza SRWebSocket no _disconnect
qui perché ciò chiudere la connessione TCP al server prima il cliente ha ricevuto un primo frame di controllo in risposta. In effetti, _disconnect
in questo articolo abbatterà il socket TCP prima che il client possa persino inviare il proprio frame di chiusura al server, perché _disconnect
in definitiva chiama _pumpWriting
prima di closeWithCode:
can. Il server probabilmente risponderà con sufficiente garbo, ma non è conforme e non sarà possibile inviare codici di chiusura univoci, mentre le cose sono impostate in questo modo.
questo è correttamente trattati in handleCloseWithData:
if (self.readyState == SR_OPEN) {
[self closeWithCode:1000 reason:nil];
}
dispatch_async(_workQueue, ^{
[self _disconnect];
});
Questo blocco gestisce Chiudere Richieste avviate sia dal client e il server. Se il server invia il primo frame di chiusura, il metodo viene eseguito secondo la sequenza che hai disposto, terminando infine in _pumpWriting
tramite closeWithCode:
, in cui il client risponderà con il proprio frame di chiusura. Quindi continua a ridurre la connessione con quello _disconnect
.
Quando il client invia il frame per primo, closeWithCode:
viene eseguito una volta senza chiudere la connessione TCP perché _closeWhenFinishedWriting
è ancora falso. Ciò consente l'ora del server di rispondere con un proprio Chiudi frame, che normalmente risultare in esecuzione closeWithCode:
nuovamente, ma per il seguente blocco nella parte superiore di tale metodo:
if (self.readyState == SR_CLOSING || self.readyState == SR_CLOSED) {
return;
}
Poiché il readyState è cambiata nel primo iterazione di closeWithCode:
, questa volta semplicemente non verrà eseguito.
La correzione dei bug di emp è necessaria per fare in modo che tutto funzioni come previsto, altrimenti il riquadro Chiudi dal server non esegue nulla. La connessione finirà comunque, ma in modo impervio, perché il server (avendo entrambi inviato e ricevuto i suoi frame) interromperà il socket alla sua estremità, e il client risponderà con uno NSStreamEventEndEncountered:
, che è normalmente riservato agli errori di streaming causati da perdite improvvise di connettività. Un approccio migliore sarebbe determinare il motivo per cui il frame non esce mai da _innerPumpScanner
a handleCloseWIthData:
. Un altro problema da tenere a mente è che per impostazione predefinita, close
chiama semplicemente closeWithCode:
con un codice di non conformità RFC di -1. Questo ha gettato errori sul mio server fino a quando non l'ho cambiato per inviare uno dei valori accettati.
Tutto ciò che ha detto: il metodo delegato non funziona perché si sta disattivando il delegato subito dopo aver chiamato close
. Tutto in close
si trova all'interno di un blocco asincrono; non ci sarà un delegato rimasto da chiamare entro il momento in cui invochi il numero didCloseWithCode:
indipendentemente da cos'altro fai qui.
cosa restituisce questa condizione "if (! Self.webSocket)"? –
significa che il websocket non può essere chiuso se è nullo, perché non è comunque aperto –
Ricevo sempre questo errore e Test to Speech interruzione audio, WebSocket chiuso con motivo [1000]: Terminazione manuale socket connessione Qualche suggerimento? –