2010-12-13 1 views
2

Ich lerne über Reaktive Erweiterungen und versuche, etwas von meinem Code neu zu factorisieren.Observable.FromAsyncPattern mit UDPClient.EndReceive und ref remote Endpunkt Parameter

UDPClient.EndReceive nimmt einen ref IPEndPoint Parameter, so habe ich zur Zeit diese Arbeit:

UdpClient receiverUDP = new UdpClient(); 
receiverUDP.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
receiverUDP.EnableBroadcast = true; 
receiverUDP.Client.ExclusiveAddressUse = false; 
receiverUDP.Client.Bind(new IPEndPoint(IPAddress.Any, 1234)); 

IPEndPoint ep = null; 
var async = Observable.FromAsyncPattern<byte[]>(receiverUDP.BeginReceive, (i) => receiverUDP.EndReceive(i, ref ep)); 
var subscr = async().Subscribe(x => Console.WriteLine(ASCIIEncoding.ASCII.GetString(x))); 

Was passiert, wenn meine Abonnenten Zugriff auf die Remote IPEndPoint benötigen? In meiner aktuellen Inkarnation verwende ich Ereignisse und gebe eine benutzerdefinierte Klasse zurück, die byte[] und IPEndPoint umschließt. Ich kann nicht für das Leben von mir, erarbeiten, wie man das mit Rx macht.

Antwort

3

Für jemand anderes suchen, ist es eine etwas einfachere und modernere Art und Weise zu tun dies mit ReceiveAsync:

public static IObservable<UdpReceiveResult> UdpStream(IPEndPoint endpoint) 
{ 
    return Observable.Using(() => new UdpClient(endpoint), 
     udpClient => Observable.Defer(() => 
      udpClient.ReceiveAsync().ToObservable()).Repeat()); 
} 

Sie können es mit IPAddress.Any nennen:

var stream = UdpStream(new IPEndPoint(IPAddress.Any, 514)); 

und verwenden Sie dann Select, um den Stream in den gewünschten Dateityp zu projizieren.

+0

Dies ist die richtige Antwort, da es der neueste Weg ist, es zu tun ... – Tim

6

Wenn Sie bereits eine Wrapper-Klasse für byte[] und IPEndPoint erstellt warum nicht zurück, dass als Folge Select mit:

private IObservable<RemoteData> GetRemoteDataAsync() 
{ 
    return Observable.Defer(() => 
    { 
     UdpClient receiverUDP = new UdpClient(); 
     receiverUDP.Client.SetSocketOption(SocketOptionLevel.Socket, 
      SocketOptionName.ReuseAddress, true); 
     receiverUDP.EnableBroadcast = true; 
     receiverUDP.Client.ExclusiveAddressUse = false; 
     receiverUDP.Client.Bind(new IPEndPoint(IPAddress.Any, 1234)); 

     IPEndPoint ep = null; 
     return Observable.FromAsyncPattern<byte[]>(
        receiverUDP.BeginReceive, 
        (i) => receiverUDP.EndReceive(i, ref ep) 
       )() 
       .Select(bytes => new RemoteData(bytes, ep)); 
    }); 
} 
+0

'System.Func >' enthält keine Definition für 'Select' – Tim

+0

geändert: var func = Observable.FromAsyncPattern ( receiverUDP.BeginReceive, (i) => receiverUDP.EndReceive (i, ref ep) ); Rückgabe func(). Wählen Sie (Bytes => neue UDPMessage (Bytes, ep)); – Tim

+0

Guter Punkt, ich habe einen Methodenaufruf zu meinem Original-Beispiel hinzugefügt –

Verwandte Themen