in Architettura Software, Informatica

Chiusura corretta di un websocket c#

Il documento RFC 6455 definisce il protocollo WebSocket. All’interno del documento sono definite tutte le specifiche per poter utilizzare in maniera corretta la comunicazione tra end-point. In particolare, dovendo implementare la chiusura della connessione, ho dovuto implementare quello che viene definito nel documento “Closing-Handshake”.

Il “Closing Handshake” è descritto nella Sezione 1.4 e sembra relativamente semplice. Il client o il server invia un frame Close (i WebSocket prendono in prestito molta terminologia TCP, quindi si scambiano dati in “frame”) e l’altra parte invia indietro il proprio frame Close in risposta, quindi entrambe le parti possono chiudere le proprie connessioni . Questo tipo di meccanismo viene normalmente utilizzando quando uno dei due peer ha la necessità di chiudere la connessione informando la controparte.

In .net core, il flusso per la chiusura della connessione è il seguente:

  • Entrambe le parti sono nello stato Open 
  • “A” manda un Close frame
  • “A” cambia il suo stato su CloseSent
  • “B” riceve il Close frame
  • “B” cambia il suoo stato in  CloseReceived
  • “B” manda un acknowledgement del Close frame
  • “B” cambia il suo stato in Closed
  • “A” riceve un acknowledgement
  • “A” cambia il suo stato in Closed
  • entrambe le parti sono disconnesse

Questo è il flusso che normalmente dovrebbe essere rispettato per procedere con una chiusura corretta.

E’ possibile gestire il flusso anche utilizzando la funzione ReceiveAsync che permette di ricevere dati dal websocket. Questa funzione prevede la possibilità di impostare un Timeout, che viene fatto scattare nel caso in cui non venga ricevuto alcun messaggio per un tempo specificato. Quello che è piuttosto insolito è il meccanismo che viene utilizzato per intercettare il superamento del tempo: viene lanciata un’eccezione che mette lo stato del websocket in Aborted, rendendolo di fatto non piu utilizzabile. Tutto quello che si può fare, è gestire il meccanismo di Dispose, liberando le risorse che non sono piu utilizzabili. Dall’altra parte della connessione il client riceverà un messaggio del tipo The remote party closed the WebSocket connection without completing the close handshake”.

In tutte quelle situazioni in cui ci possono essere problemi di connessione (ad esempio la perdita di connessione tra client e server), l’utilizzo del token in ReceiveAsync può risultare la scelta adeguata, anche se in processi realtime la perdita di connessione deve essere gestita con timeout corretti per l’applicazione.