2009-04-03 1 views
6

'간헐적으로 연결된'LOB (기간 업무) 응용 프로그램으로 사용되는 .NET Compact Framework 3.5 프로그램이 있습니다. 온라인 웹 서비스를 볼 수 있다면 데이터 액세스 용으로 사용하지만 네트워크 연결이 끊어지면 로컬 캐시를 사용합니다.Windows Mobile에서 네트워크 상태를 가장 잘 관리하는 방법

모든 연결 옵션과 상태 변경을 처리하는 가장 좋은 방법은 무엇입니까?

  • OpenNetCF의 ConnectionManager 클래스?
  • Microsoft.WindowsBile.State.SystemState?
  • API 호출?

어떻게하면 WiFi, Cradle 및 GPRS의 차이점을 이해하고 사용할 수있는 최상의 방법을 사용할 수 있습니까?

누구든지 이에 대한 지침이 있습니까?

답변

2

난 그냥 내가 이런 식으로 호출 할 수있는 간단한 공유 클래스 생성 : 다음

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

내 실제 비즈니스의 모든 클래스를/기능은 UI 코드에서이 불결함을 숨기기 위해 이것을 사용할 수 있습니다.

MyConnectionClass '는, isConnected 속성은이 같은 것을 할 것이다 :

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 

또한 당신이 백그라운드 스레드를 사용하여 연결 상태를 폴링 때 상태 다음 주 응용 프로그램 스레드에 다시 이벤트를 발생하는 것이 좋습니다 변경. 여기에 자세한 작성자는 다음과 같습니다

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

편집 : GPRS 지금

, 지원 :

당신이 웹 요청 또는 웹 서비스를 사용하는 경우 프레임 워크는 처리합니다 당신을위한 연결.당신이하여 TcpClient 또는 UDPClient에 깊은 다이빙을하는 경우, 당신과 같이 연결 관리자 API와 함께 처리 할 자신있어 필요

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

그리고 그것을 사용하려면 다음을 수행하십시오

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

이 앤서니 출신 여기에 왕의 블로그 :

Anthony Wong

는 그리고 기억 만 낮은 수준의 TCP 나 UDP 물건이 필요합니다. HTTPRequests는 이것을 필요로하지 않습니다.

+0

GPRS 연결이 가능하다고 말하면 연결을 시도하려면 어떻게해야합니까? 게시 된 방법 (및 링크)은 연결이 켜져 있거나 꺼져있는 WiFi처럼 보일뿐입니다. – JasonRShaver

1

Microsoft.WindowsMobile.Status 네임 스페이스에서 SystemState 클래스를 사용하면 어떨까요? 상태가 변경되면 시스템의 현재 상태를 모니터링하고 알림을받을 수 있습니다. 일부 코드는 post을 참조하십시오.

SystemState는 연결 상태에 관한 것입니다. ConnectionManager를 통해 특정 연결을 사용할 수 있습니다. 나는이 article을 읽는 것이 좋습니다. .NET Compact Framework 3.5를 사용하는 경우 관리되는 API가 포함됩니다. OpenNetCF ConnectionManager를 사용할 수도 있습니다.

+0

SystemState를 사용하여 연결하려고 시도하는 방법 (GPRS를 사용할 수있는 경우 시작)은 어떻게해야합니까? – JasonRShaver

1

모바일 앱을 작성하려고하는데 네트워크가 관련되어 있는지 알지 못합니다. 나는 충분한 양의 밸리데이션 데이터를 로컬에서 유지하고, 연결되어있는 동안 지워지는 로컬 큐에 트랜잭션을 작성한다. 대기열 판독기는 연결되지 않은 경우 다시 시도하기위한 타이머를 포함합니다. 대기열 메시지는 양방향이므로 로컬 새로 고침도 제공 할 수 있습니다. 기본 메시지 큐 패턴.

이렇게하면 휴대 성이 뛰어난 기본 소켓 열기/닫기/읽기/쓰기/ioctl 로직을 사용하여 네트워크 연결을 가장 간단하게 처리 할 수 ​​있습니다. 중요한 시간 동안 연결을 유지할 필요가 없습니다. (IMHO를 해결하지 못했지만 지난 몇 년 동안 모든 MS 아키텍처 변형과 동기화 상태를 유지하는 것이 무엇인지 상상하기 싫었습니다.)

+0

당신이 쓴 것과 많은 것에 동의합니다. WiFi가 없으면 SMS를 프로토콜로 사용하도록 전환하는 모바일 앱이있었습니다. 이는 CE 용 CLSA에 내장 된 'Message Queue'기반 xfer 시스템 덕분에 쉽게 할 수있었습니다. 나는 아직도 그것을 사용할 수 있었으면 좋겠지 만 그 프로젝트는 전화 옵션을 떨어 뜨렸다. = ( – JasonRShaver

1

Microsoft.WindowsMobile.State 네트워크 연결에 대한 시스템 상태보고는 신뢰할 수 없습니다. 이것은 6.0 이전이었습니다. 나는 철저한 테스트를 수행하지는 않았지만 거기에 연결이 없다고 말할 때 버려졌습니다.