2009-04-03 9 views
6

Tengo un programa .NET Compact Framework 3.5 que se utiliza como una aplicación de línea de negocios ('LOB') 'Ocasionalmente conectada'. Si puede ver un servicio web en línea, lo usará para el acceso a datos, pero si se pierde la conexión de red usará un caché local.La mejor manera de administrar el estado de la red en Windows Mobile

¿Cuál es la mejor manera de manejar todas las opciones de conexión y los cambios de estado?

  • Clase de ConnectionManager de OpenNetCF?
  • Microsoft.WindowsBile.State.SystemState?
  • Llamadas a API?

¿Cómo entiendes la diferencia entre WiFi, Cradle y GPRS y utilizas el mejor método disponible?

¿Alguien tiene alguna orientación sobre esto?

Respuesta

2

acabo de crear una clase compartida sencilla que puedo llamar así:

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

Entonces todas mis clases de negocios reales/funciones se pueden usar esto para ocultar esta porquería a partir del código de interfaz de usuario.

propiedad isConnected El MyConnectionClass' tendría algo como esto:

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 

También se recomienda que la encuesta en el estado de conexión utilizando un hilo de fondo y luego desencadenar un evento posterior a la del hilo principal aplicación cuando el Estado cambios. Esta es la valoración crítica detallada:

Testing for and responding to network connections in the .NET Compact Framework

EDIT:

Ahora, por GPRS apoyo:

Si está utilizando Peticiones Web o Web Services, el marco se encargará de la conexión para ti.Si vas a bucear más profundamente en TCPClient o UDPClient, es necesario manejarlo con la API de Administrador de conexiones de sí mismo de esta manera:

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); 
} 

Y para usarlo, hacer esto:

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"); 
     } 
    } 

Ésta era de Anthony el blog de Wong aquí:

Anthony Wong

Y recuerda que sólo es necesario para este menor nivel de TCP o UDP cosas. HTTPRequests no necesita esto.

+0

¿Cómo le digo que intente conectarme (es decir, inicie GPRS si está disponible)? El método publicado (y el enlace) parece que solo se dirige a WiFi, donde la conexión está activada o desactivada. – JasonRShaver

1

¿Qué hay de usar la clase SystemState en el espacio de nombres Microsoft.WindowsMobile.Status? Puede supervisar el estado actual del sistema y recibir notificaciones cuando cambia el estado. Consulte este post para obtener algún código.

SystemState trata solo sobre el estado de las conexiones. Puede usar una conexión específica a través del ConnectionManager. Recomiendo leer esto article. Si está usando .NET Compact Framework 3.5, se incluye una API administrada. También puede usar OpenNetCF ConnectionManager.

+0

¿Cómo se utiliza la SystemState para indicarle que debe tratar de conectar (es decir, comenzar GPRS si está disponible)? – JasonRShaver

1

trato de escribir aplicaciones móviles por lo que ni siquiera saben que hay una red en cuestión. Guardo datos de validación suficientemente buenos localmente y luego escribo transacciones en una cola local que se borra mientras está conectado; el lector de cola incluye un temporizador para volver a intentar cuando no está conectado. Los mensajes de cola son bidireccionales, por lo que también se pueden suministrar actualizaciones locales. Patrones básicos de Message Queue.

Esto me permite tratar la conexión de red en la forma más sencilla, utilizando cerca de la lógica toma básica de apertura// leer/escribir/ioctl que es altamente portátil; y sus conexiones no necesitan persistir durante un tiempo significativo en absoluto. (No me gustaría imaginar lo que se necesitaría para mantenerme sincronizado con todas las variaciones de la arquitectura MS en los últimos años, que aún no se ha solucionado en mi humilde opinión.)

+0

Estoy muy de acuerdo con lo que escribiste, tenía una aplicación móvil que cuando no hay WiFi se cambiará a usar SMS como protocolo. Eso fue fácil de hacer debido a un sistema xfer basado en 'Message Queue' que incorporé a CLSA para CE. Desearía poder seguir usándolo pero ese proyecto dejó caer la opción de teléfono = ( – JasonRShaver

1

Encontré el Microsoft.WindowsMobile.State . Informes de SystemState de las conexiones de red no son confiables. Esto fue 6.0 y antes. No hice pruebas exhaustivas pero fue abandonado cuando decía que no había conexión cuando había.

Cuestiones relacionadas