Remoting provides support for events. The client code can simply subscribe to an event that's exposed by the server class. (There are a large list of caveats here).
Also, you can pass a callback interface to a remote class, providing your implementation of the interface is a MarshalByRef object.
interface IMyCallback
{
void OnSomethingHappened(string information);
}
class MyCallbackImplementation : MarshalByRefObject, IMyCallback
{
public void OnSomethingHappened(string information)
{
// ...
}
}
class MyServerImplementation : MarshalByRefObject
{
List<IMyCallback> _callbacks = new List<IMyCallback>();
public void RegisterCallback(IMyCallback _callback)
{
_callbacks.Add(_callback);
}
public void InvokeCalbacks(string information)
{
foreach(IMyCallback callback in _callbacks)
{
_callback.OnSomethingHappened(information);
}
}
}