2011-03-29 98 views
1

我想弄清楚什麼是處理異步對象傳輸的最佳方法。C#異步對象傳輸(套接字?)

我想要做的是通過連接到一臺服務器的網絡連接(5-10個客戶端)打開同一個應用程序的多個實例,並且當其中一個應用程序更新其數據時,我需要傳輸該更新到所有其他實例。

更新對象將與此類似:

public class UpdateData 
{ 
    public double Angle { get; set; } 
    public double Azimuth { get; set; } 
    public Point Position { get; set; } 
    public Guid ObjectGuid { get; set; } 
} 

的數據將不會很大,但這種類型的對象將從每個客戶機傳輸每秒約10-50倍於所有其他客戶。

處理這種數據傳輸的最佳方式是什麼?

我當時的想法是有一個服務器對象聽,並使用類似這樣的東西接受連接:

private void BtConnectClick(object sender, EventArgs e) 
    { 
     int port; 

     if (!int.TryParse(tbPort.Text, out port)) 
     { 
      MessageBox.Show("Please enter a valid port into the textbox"); 
      tbPort.Text = ""; 
      return; 
     } 

     try 
     { 
      _listener = new TcpListener(IPAddress.Any, port); 
      _listener.Start(); 

      _listener.BeginAcceptSocket(OnClientConnect, _listener); 

     } 
     catch (SocketException se) 
     { 
      MessageBox.Show(se.Message); 
     } 

    } 

    public void OnClientConnect(IAsyncResult asyn) 
    { 
     try 
     { 
      var s = _listener.EndAcceptSocket(asyn); 

      _clients.Add(s); // List<Socket> object 
     } 
     catch (SocketException se) 
     { 
      MessageBox.Show(se.Message); 
     } 
    } 

但是應該如何處理服務器的數據傳輸?

我知道我應該試圖從_clients的所有套接字接收數據,並且一旦我收到數據,我需要將它轉發到_clinets中的所有其他套接字上,但我該怎麼做?當客戶端終止其連接時,應該如何以及在哪裏檢測?

此外,客戶端應該監聽從服務器接收的數據以及將數據發送到服務器。我可以使用一個套接字處理所有這些事情,還是應該使用2?

感謝您的幫助!

+0

我想知道......你必須自己做這個嗎?有一些預先滾動的消息總線。哎呀,你可以使用redis來做這件很漂亮的事情(pub/sub)... – 2011-03-29 16:54:59

+0

我不必自己做。我不完全是家庭的'redis',你能否詳細說明一下? – 2011-03-29 16:58:58

+0

redis是嚴格意義上的*(免費)緩存服務器,但它包含pub/sub。您的聽衆向某個指定頻道發佈SUBSCRIBE,發行商向該頻道發佈PUBLISH:因此,您發送的任何數據塊都會分發給所有聽衆。你可以很容易地找到c#的綁定,或者我有一個完全異步的在這裏,我想讓傑夫讓我作爲一個小型項目發佈... – 2011-03-29 17:03:33

回答

1

就我個人而言,我會把它留給消息總線/服務總線或任何其他帶有pub/sub的東西。我的首選項是redis:http://redis.io/commands#pubsub

重新對象,我會使用protobuf-net,只是因爲我知道它會產生上述消息的小二進制文件。將BLOB發送(發佈)到指定的redis頻道將使其分發給該頻道上的所有收聽者。

+0

好吧,這絕對是做事的簡單方法。謝謝! – 2011-03-29 19:23:30