23 messaggi dal 18 febbraio 2011
Salve,
sto iniziando ad interessarmi a SignalR e vorrei porvi una domanda: da quanto ho capito a differenza dell'http classico con SignalR è il server che contatta i client per inviare messaggi.

Quello che non mi è chiaro però è come fa il server a sapere quali client sono in attesa.

Spiego meglio: ho seguito gli esempi di Microsoft per creare una chat su un'hosting con Aruba e se apro 2 tab sul browser inserendo l'indirizzo del sito dell'applicazione arrivano i messaggi dell'uno all'altro e viceversa.

Se io volessi invece far arrivare un messaggio ad un altro client, ad esempio una scheda raspberry collegata ad internet, come dovrei fare? come faccio a dire al server che deve inviare un messaggio a questa scheda? dovrei impostare il suo ip nell'applicazione? dovrei prima far chiamare l'indirizzo dalla scheda?

Scusate l'ignoranza ma questa cosa è nuova per me.

Grazie per tutti i consigli che potrete darmi.
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


da quanto ho capito a differenza dell'http classico con SignalR è il server che contatta i client per inviare messaggi.

Non precisamente.
Anche nel caso di SignalR è il client a iniziare la connessione con il server. Questa connessione è persistente, cioè resta aperta finché il client è connesso e permette ad entrambe le parti di scambiarsi messaggi liberamente.


Quello che non mi è chiaro però è come fa il server a sapere quali client sono in attesa.

SignalR, lato server, mantiene internamente un elenco dei client connessi.


Se io volessi invece far arrivare un messaggio ad un altro client, ad esempio una scheda raspberry collegata ad internet, come dovrei fare?

Usando i gruppi, ma procediamo per gradi.
Ogni volta che un client si collega, gli viene assegnato un ConnectionId. Questo valore non è predicibile, quindi se si collegano 10 client, tu non puoi sapere quale di quelli è la raspberry PI.
Bisogna che la raspberry PI dica qualcosa di sé stessa al server. Per esempio, potrebbe chiedere di unirsi a un gruppo dal nome noto, come per esempio un GUID che la rappresenta. Il GUID può essere totalmente arbitrario o calcolato.

Tu nel database del server avrai una tabella "dispositivi" che mantiene la corrispondenza tra quel GUID e la raspberry pi. Se hai 10 raspnerry pi, ognuna avrà il proprio GUID univoco.

Quando ti colleghi tu dal browser, dovrai mostrare nella pagina web l'elenco dei dispositivi. Quando ne scegli uno, ti unirai al gruppo che come nome porta il GUID relativo al dispositivo. A questo punto, dato che sia tu e sia la raspberry pi siete collegati allo stesso gruppo, vi potete scambiare messaggi.

Ecco la documentazione sui gruppo di SignalR per ASP.NET Core.
https://docs.microsoft.com/it-it/aspnet/core/signalr/groups?view=aspnetcore-2.2

Oppure, se è per utilizzo professionale, potresti valutare un servizio apposito come IoT Hubs di Azure che ha tante funzionalità specifiche per i dispositivi IoT.
https://azure.microsoft.com/it-it/services/iot-hub/

ciao,
Moreno

Enjoy learning and just keep making
23 messaggi dal 18 febbraio 2011
Ti ringrazio subito per la risposta dettagliata.
Come prima cosa ho capito che è sempre il client ad iniziare la connessione, e già questo mi ha chiarito tanti dubbi che avevo!

Per capire quale scheda si è collegata dovrei creare una tabella inserendo ad es. :
8B234B8D-7DFE-441B-BA5C-B64E5FFF7FDD -> raspberry1
DHJYUI67-8GFE-4H6B-4R55-DJH65FFF7FDD -> raspberry2

Poi dovrei collegarmi all'app dalla raspberry inviando come parametro il GUID assegnato, in modo tale da fare una ricerca sulla tabella per quel GUID e capire che quella connessione fa capo a quella scheda.

Però poi non mi è molto chiaro il resto: come faccio in pratica a mandare un comando solo a quella rapsberry?
Sto facendo ricerche su google ma non è molto semplice capire come funziona...almeno per me.

Grazie per il tempo dedicatomi.
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao, prego!


Poi dovrei collegarmi all'app dalla raspberry inviando come parametro il GUID assegnato,

Sì, ma chiarisco meglio.
  • Passo 1. Quando la raspberry PI si accende, dovrai fare in modo che ci sia un demone (cioè un servizio di Linux) che parte all'avvio del dispositivo. Tu in che linguaggio e con che piattaforma stai realizzando l'applicazione che installi sulla raspberry PI?
  • Passo 2. Il demone in questione si collega all'applicazione ASP.NET tramite SignalR;
  • Passo 3. A connessione stabilita, invia il suo GUID via SignalR. Il server verifica se quel GUID esiste nel database e, se sì, la aggiungerà a un gruppo SignalR che porta quel GUID come nome.


Ecco come si usano i gruppi SignalR.
https://www.aspitalia.com/script/1123/Gestire-Gruppi-Hub-ASP.NET-SignalR.aspx
Questo era per ASP.NET. Tu usi ASP.NET o ASP.NET Core?


Però poi non mi è molto chiaro il resto: come faccio in pratica a mandare un comando solo a quella rapsberry?

Invii il messaggio al gruppo che porta il GUID come nome. La raspberry PI riceverà il messaggio perché in precedenza di era unita a quel gruppo.

Attenzione! Se la raspberry pi in quel momento è spenta, il messaggio sarà perso per sempre.

ciao,
Moreno

PS. Questa è la soluzione che ti richiede meno codice possibile. Se poi vuoi mantenere un elenco di tutte le raspberry pi collegate, puoi anche fare a meno dei gruppi e gestire tu da codice C# la corrispondenza tra il Guid del dispositivo e il connection ID che ha ottenuto alla connessione.

Se questo è un progetto per hobby, può anche andar bene così. Metterei giusto un minimo di autenticazione, altrimenti qualunque client potrebbe impersonare una raspberry pi se ne conescesse il GUID.
Se invece è un progetto lavorativo, dovresti usare soluzioni apposite come IoT Hub di Azure.
Modificato da BrightSoul il 25 maggio 2019 18:43 -
Modificato da BrightSoul il 25 maggio 2019 18:45 -

Enjoy learning and just keep making
23 messaggi dal 18 febbraio 2011
Ciao,
il linguaggio sulla raspberry è C++, mentre sul server utilizzo Asp.net.
Quando dici " Il demone in questione si collega all'applicazione ASP.NET tramite SignalR;" intendi il SignalR che è caricato sulla pagina del server, quella a cui punterà il demone della raspberry, giusto?

In pratica:
- il demone della scheda punta all'url del mio sito in cui è presente SignalR;
- viene tentata la connessione;
- se tutto ok poi il server dovrebbe inviare una risposta alla scheda?
- la scheda dovrebbe gestire la risposta del server (ad es. connessione ok) e questa successivamente invia il suo GUID?
- il server riceve il GUID, fa tutte le verifiche del caso, e inizia la procedura di aggiunta al gruppo;
- se tutto ok il server invia msg a quel gruppo che viene quindi ricevuto dalla scheda.

E' corretto quello che ho scritto?

Grazie mille per l'aiuto.
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao, prego!


Quando dici " Il demone in questione si collega all'applicazione ASP.NET tramite SignalR;" intendi il SignalR che è caricato sulla pagina del server, quella a cui punterà il demone della raspberry, giusto?

Sì, anche se va precisato.
SignalR non è propriamente "caricato sulla pagina del server".
Il demone si dovrà collegare ad un URL ben preciso, che non restituisce una "pagina" web ma permette a client e server di scambiare messaggi.

Ecco il client C++ che dovrai usare dall'applicazione C++
https://github.com/SignalR/SignalR-Client-Cpp
Lì ci trovi anche degli esempi. Guarda come è fatto l'HubConnectionSample.
[url]https://github.com/SignalR/SignalR-Client-Cpp/tree/dev/samples/HubConnectionSample


Vediamo punto per punto.

- il demone della scheda punta all'url del mio sito in cui è presente SignalR;

Sì, lo vedi qui
https://github.com/SignalR/SignalR-Client-Cpp/blob/e73faf108d4b3c759ace191b13a215f6c1eac201/samples/HubConnectionSample/HubConnectionSample.cpp#L30


- viene tentata la connessione;

Sì, ecco la riga di codice:
https://github.com/SignalR/SignalR-Client-Cpp/blob/e73faf108d4b3c759ace191b13a215f6c1eac201/samples/HubConnectionSample/HubConnectionSample.cpp#L37


- se tutto ok poi il server dovrebbe inviare una risposta alla scheda?

Sì, gli manda una conferma di connessione automaticamente e tu lato server non devi fare niente di esplicito.


- la scheda dovrebbe gestire la risposta del server (ad es. connessione ok) e questa successivamente invia il suo GUID?

Lato client C++, potrai eseguire del codice a connessione avvenuta. Lo vedi qui. E' in questo punto che dovrai inviare un messaggio al server per comunicare il Guid.
https://github.com/SignalR/SignalR-Client-Cpp/blob/e73faf108d4b3c759ace191b13a215f6c1eac201/samples/HubConnectionSample/HubConnectionSample.cpp#L40


- il server riceve il GUID, fa tutte le verifiche del caso, e inizia la procedura di aggiunta al gruppo;
- se tutto ok il server invia msg a quel gruppo che viene quindi ricevuto dalla scheda.

Esatto.

Però non mi hai ancora detto se è un progetto per hobby o per scopo professionale/industriale. Se è quest'ultimo, ci sono considerazioni da fare sulla sicurezza.

Moreno

Enjoy learning and just keep making
23 messaggi dal 18 febbraio 2011
Per adesso è solo per vedere se riesco ad implementare un progetto funzionante... poi vorrei utilizzarlo per qualche progetto concreto: ci sono molti aspetti da considerare in quest'ultimo caso lato sicurezza?

Intanto vediamo se nei prossimi giorni riesco a ottenere qualcosa.

Ti ringrazio per la disponibilità.
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,


ci sono molti aspetti da considerare in quest'ultimo caso lato sicurezza?

Beh, sì perché con la soluzione che ti ho suggerito, la raspberry PI si limita a inviare il suo Guid e il server "si fida" di ciò che gli viene mandato senza attuare alcuna verifica.
Qui l'unico meccanismo di "sicurezza", se così vogliamo chiamarlo, risiede nel fatto che il Guid sia noto solo alla raspberry pi e al server. Però la sicurezza tramite segretezza NON è sicurezza".

Per migliorare la situazione, oltre al GUID dovresti generare anche una chiave segreta, diversa per ogni raspberry pi, che è conosciuta solo dalla raspberry pi e dal server e che non viene mai inviata in rete.
Usa la chiave segreta per firmare un token JWT in cui metti il Guid del dispositivo, un nonce e una data di scadenza breve, così da avere una maggiore protezione da attacchi replay.

Il server riceve il token JWT e, se risulta tutto integro e verificato, allora a quel punto è sicuro aggiungere il dispositivo al gruppo SignalR.

Lato client, fai in modo che gli utenti siano autenticati prima di consentirgli l'invio di messaggi ai dispositivi.

Quello che ti ho descritto è l'intervento minimo ma per questioni professionali io ti consiglio di usare IoT Hubs di Azure.

ciao,
Moreno

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.