/// <summary> /// Constructs a DefaultRemoteManager listening on the specified address and any /// available port. /// </summary> /// <param name="localAddress">The address to listen on</param> /// <param name="port">The port to listen on</param> /// <param name="codec">The codec used for serializing messages</param> public DefaultRemoteManager(IPAddress localAddress, int port, ICodec <T> codec) { if (localAddress == null) { throw new ArgumentNullException("localAddress"); } if (port < 0) { throw new ArgumentException("Listening port must be greater than or equal to zero"); } if (codec == null) { throw new ArgumentNullException("codec"); } _observerContainer = new ObserverContainer <T>(); _codec = new RemoteEventCodec <T>(codec); _cachedClients = new Dictionary <IPEndPoint, ProxyObserver>(); IPEndPoint localEndpoint = new IPEndPoint(localAddress, port); // Begin to listen for incoming messages _server = new TransportServer <IRemoteEvent <T> >(localEndpoint, _observerContainer, _codec); _server.Run(); LocalEndpoint = _server.LocalEndpoint; Identifier = new SocketRemoteIdentifier(LocalEndpoint); }
/// <summary> /// Returns an IObserver used to send messages to the remote host at /// the specified IPEndpoint. /// </summary> /// <param name="remoteEndpoint">The IPEndpoint of the remote host</param> /// <returns>An IObserver used to send messages to the remote host</returns> public IObserver <T> GetRemoteObserver(RemoteEventEndPoint <T> remoteEndpoint) { if (remoteEndpoint == null) { throw new ArgumentNullException("remoteEndpoint"); } SocketRemoteIdentifier id = remoteEndpoint.Id as SocketRemoteIdentifier; if (id == null) { throw new ArgumentException("ID not supported"); } return(GetRemoteObserver(id.Addr)); }
/// <summary> /// Registers an IObserver used to handle incoming messages from the remote host /// at the specified IPEndPoint. /// The IDisposable that is returned can be used to unregister the IObserver. /// </summary> /// <param name="remoteEndpoint">The IPEndPoint of the remote host</param> /// <param name="observer">The IObserver to handle incoming messages</param> /// <returns>An IDisposable used to unregister the observer with</returns> public IDisposable RegisterObserver(RemoteEventEndPoint <T> remoteEndpoint, IObserver <T> observer) { if (remoteEndpoint == null) { throw new ArgumentNullException("remoteEndpoint"); } SocketRemoteIdentifier id = remoteEndpoint.Id as SocketRemoteIdentifier; if (id == null) { throw new ArgumentException("ID not supported"); } return(RegisterObserver(id.Addr, observer)); }
/// <summary> /// Constructs a DefaultRemoteManager. Does not listen for incoming messages. /// </summary> /// <param name="codec">The codec used for serializing messages</param> public DefaultRemoteManager(ICodec <T> codec) { using (LOGGER.LogFunction("DefaultRemoteManager::DefaultRemoteManager")) { if (codec == null) { throw new ArgumentNullException("codec"); } _observerContainer = new ObserverContainer <T>(); _codec = new RemoteEventCodec <T>(codec); _cachedClients = new Dictionary <IPEndPoint, ProxyObserver>(); LocalEndpoint = new IPEndPoint(NetworkUtils.LocalIPAddress, 0); Identifier = new SocketRemoteIdentifier(LocalEndpoint); } }
/// <summary> /// Look up the IObserver for the registered IPEndPoint or event type /// and execute the IObserver. /// </summary> /// <param name="transportEvent">The incoming remote event</param> public void OnNext(TransportEvent <IRemoteEvent <T> > transportEvent) { IRemoteEvent <T> remoteEvent = transportEvent.Data; remoteEvent.LocalEndPoint = transportEvent.Link.LocalEndpoint; remoteEvent.RemoteEndPoint = transportEvent.Link.RemoteEndpoint; T value = remoteEvent.Value; bool handled = false; IObserver <T> observer1; IObserver <IRemoteMessage <T> > observer2; if (_universalObserver != null) { _universalObserver.OnNext(value); handled = true; } if (_endpointMap.TryGetValue(remoteEvent.RemoteEndPoint, out observer1)) { // IObserver was registered by IPEndpoint observer1.OnNext(value); handled = true; } else if (_typeMap.TryGetValue(value.GetType(), out observer2)) { // IObserver was registered by event type IRemoteIdentifier id = new SocketRemoteIdentifier(remoteEvent.RemoteEndPoint); IRemoteMessage <T> remoteMessage = new DefaultRemoteMessage <T>(id, value); observer2.OnNext(remoteMessage); handled = true; } if (!handled) { throw new WakeRuntimeException("Unrecognized Wake RemoteEvent message"); } }