Il modo migliore per gestire lo stato della rete in Windows Mobile

Ho un programma .NET Compact Framework 3.5 che viene utilizzato come applicazione Line of Business (LOB) “Occasionally Connected”. Se può vedere un servizio web online, lo utilizzerà per l’accesso ai dati, ma se la connessione di rete viene persa userà una cache locale.

Qual è il modo migliore per gestire tutte le opzioni di connessione e le modifiche di stato?

  • La class ConnectionManager di OpenNetCF?
  • Microsoft.WindowsBile.State.SystemState?
  • Chiamate API?

Come fai a capire la differenza tra WiFi, Cradle e GPRS e utilizzare il miglior metodo disponibile?

Qualcuno ha una guida su questo?

Creo solo una semplice class condivisa che posso chiamare in questo modo:

If MyConnectionClass.IsConnected then 'Do connected stuff Else 'Do local save End If 

Quindi tutte le mie effettive classi / funzioni commerciali possono utilizzare questo per hide questa cattiveria dal codice dell’interfaccia utente.

La proprietà IsConnected di MyConnectionClass avrebbe qualcosa del genere:

 Public ReadOnly Property IsConnected As Boolean Get Try Dim HostName As String = Dns.GetHostName() Dim thisHost As IPHostEntry = Dns.GetHostByName(HostName) Dim thisIpAddr As String = thisHost.AddressList(0).ToString return (thisIpAddr <> Net.IPAddress.Parse("127.0.0.1").ToString()) Catch ex As Exception Return False End Try End Get End Property 

Si consiglia inoltre di eseguire il polling dello stato della connessione utilizzando un thread in background e quindi generare nuovamente un evento nel thread dell’app principale quando lo stato cambia. Ecco la descrizione dettagliata:

Test e risposta alle connessioni di rete in .NET Compact Framework

MODIFICARE:

Ora, per il supporto GPRS :

Se si utilizzano richieste Web o servizi Web, il framework gestirà la connessione per conto dell’utente. Se ti stai immergendo più a fondo in TCPClient o UDPClient, devi gestirlo con le API di Connection Manager in questo modo:

 public class GPRSConnection { const int S_OK = 0; const uint CONNMGR_PARAM_GUIDDESTNET = 0x1; const uint CONNMGR_FLAG_PROXY_HTTP = 0x1; const uint CONNMGR_PRIORITY_USERINTERACTIVE = 0x08000; const uint INFINITE = 0xffffffff; const uint CONNMGR_STATUS_CONNECTED = 0x10; static Hashtable ht = new Hashtable(); static GPRSConnection() { ManualResetEvent mre = new ManualResetEvent(false); mre.Handle = ConnMgrApiReadyEvent(); mre.WaitOne(); CloseHandle(mre.Handle); } ~GPRSConnection() { ReleaseAll(); } public static bool Setup(Uri url) { return Setup(url.ToString()); } public static bool Setup(string urlStr) { ConnectionInfo ci = new ConnectionInfo(); IntPtr phConnection = IntPtr.Zero; uint status = 0; if (ht[urlStr] != null) return true; if (ConnMgrMapURL(urlStr, ref ci.guidDestNet, IntPtr.Zero) != S_OK) return false; ci.cbSize = (uint) Marshal.SizeOf(ci); ci.dwParams = CONNMGR_PARAM_GUIDDESTNET; ci.dwFlags = CONNMGR_FLAG_PROXY_HTTP; ci.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE; ci.bExclusive = 0; ci.bDisabled = 0; ci.hWnd = IntPtr.Zero; ci.uMsg = 0; ci.lParam = 0; if (ConnMgrEstablishConnectionSync(ref ci, ref phConnection, INFINITE, ref status) != S_OK && status != CONNMGR_STATUS_CONNECTED) return false; ht[urlStr] = phConnection; return true; } public static bool Release(Uri url) { return Release(url.ToString()); } public static bool Release(string urlStr) { return Release(urlStr, true); } private static bool Release(string urlStr, bool removeNode) { bool res = true; IntPtr ph = IntPtr.Zero; if (ht[urlStr] == null) return true; ph = (IntPtr)ht[urlStr]; if (ConnMgrReleaseConnection(ph, 1) != S_OK) res = false; CloseHandle(ph); if (removeNode) ht.Remove(urlStr); return res; } public static void ReleaseAll() { foreach(DictionaryEntry de in ht) { Release((string)de.Key, false); } ht.Clear(); } [StructLayout(LayoutKind.Sequential)] public struct ConnectionInfo { public uint cbSize; public uint dwParams; public uint dwFlags; public uint dwPriority; public int bExclusive; public int bDisabled; public Guid guidDestNet; public IntPtr hWnd; public uint uMsg; public uint lParam; public uint ulMaxCost; public uint ulMinRcvBw; public uint ulMaxConnLatency; } [DllImport("cellcore.dll")] private static extern int ConnMgrMapURL(string pwszURL, ref Guid pguid, IntPtr pdwIndex); [DllImport("cellcore.dll")] private static extern int ConnMgrEstablishConnectionSync(ref ConnectionInfo ci, ref IntPtr phConnection, uint dwTimeout, ref uint pdwStatus); [DllImport("cellcore.dll")] private static extern IntPtr ConnMgrApiReadyEvent(); [DllImport("cellcore.dll")] private static extern int ConnMgrReleaseConnection(IntPtr hConnection, int bCache); [DllImport("coredll.dll")] private static extern int CloseHandle(IntPtr hObject); } 

E per usarlo, fai questo:

 public void DoTcpConnection() { string url = "www.msn.com"; bool res = GPRSConnection.Setup("http://" + url + "/"); if (res) { TcpClient tc = new TcpClient(url, 80); NetworkStream ns = tc.GetStream(); byte[] buf = new byte[100]; ns.Write(buf, 0, 100); tc.Client.Shutdown(SocketShutdown.Both); ns.Close(); tc.Close(); MessageBox.Show("Wrote 100 bytes"); } else { MessageBox.Show("Connection establishment failed"); } } 

Questo è stato dal blog di Anthony Wong qui:

Anthony Wong

E ricorda che ne hai solo bisogno per cose di livello inferiore su TCP o UDP. HTTPRequests non ha bisogno di questo.

Che dire dell’utilizzo della class SystemState nello spazio dei nomi Microsoft.WindowsMobile.Status? È ansible monitorare lo stato corrente del sistema e ottenere notifiche, quando lo stato cambia. Vedi questo post per un po ‘di codice.

SystemState riguarda solo lo stato delle connessioni. È ansible utilizzare una connessione specifica tramite ConnectionManager. Consiglio di leggere questo articolo . Se si utilizza .NET Compact Framework 3.5, è inclusa un’API gestita. Puoi anche utilizzare OpenNetCF ConnectionManager.

Provo a scrivere app per dispositivi mobili in modo che non sappiano nemmeno che è coinvolta una rete. Conservo localmente dati di convalida sufficientemente validi, quindi scrivo le transazioni su una coda locale che si cancella mentre è connesso; il lettore di coda include un timer per riprovare quando non è connesso. I messaggi di coda sono bidirezionali, quindi è ansible fornire anche aggiornamenti locali. Modelli di coda dei messaggi di base.

Questo mi consente di trattare la connessione di rete nel modo più semplice, usando la logica di base open open / close / read / write / ioctl che è altamente portatile; e le tue connessioni non hanno bisogno di persistere per un periodo di tempo significativo. (Mi dispiacerebbe immaginare cosa sarebbe necessario per rimanere in sintonia con tutte le variazioni dell’architettura MS negli ultimi anni – che ancora non ha risolto IMHO.)

Ho trovato che la segnalazione Microsoft.WindowsMobile.State.SystemState delle connessioni di rete non è affidabile. Questo era 6.0 e precedenti. Non ho fatto test esaurienti, ma è stato abbandonato quando avrebbe detto che non c’era alcuna connessione quando c’era.