public static ProcessId ConnectionInbox(ProcessId hub, RelayMsg rmsg) { switch (rmsg.Tag) { case RelayMsg.MsgTag.Inbound: var inmsg = rmsg as InboundRelayMsg; if (rmsg.IsAsk) { // Ask not supported tell(Errors, "'ask' not supported from JS to server."); } else { tell(rmsg.To, inmsg.Message, rmsg.Sender.IsValid ? Self.Append(rmsg.Sender) : ProcessId.NoSender); } break; case RelayMsg.MsgTag.Outbound: fwd(hub, rmsg); break; case RelayMsg.MsgTag.Subscribe: var pid = rmsg.To; var subscriber = rmsg.Sender; var connectionId = rmsg.ConnectionId; ActorContext.SelfProcess.Actor.AddSubscription( rmsg.To, ActorContext.Observe <object>(pid).Subscribe(x => tell(hub, new OutboundRelayMsg( connectionId, new RemoteMessageDTO { MessageId = Guid.NewGuid(), Content = JsonConvert.SerializeObject(x), Sender = pid.Path, To = subscriber.Path, ContentType = x.GetType().AssemblyQualifiedName, ReplyTo = pid.Path, Tag = (int)Message.TagSpec.User, Type = (int)Message.Type.User }, subscriber, pid, false), pid))); break; case RelayMsg.MsgTag.Unsubscribe: ActorContext.SelfProcess.Actor.RemoveSubscription(rmsg.To); break; } return(hub); }
/// <summary> /// Subscribes our inbox to another process publish stream. When it calls 'publish' it will /// arrive in our inbox. /// </summary> /// <param name="pid">Process to subscribe to</param> /// <remarks> /// The process can publish any number of types, any published messages not of type T will be ignored. /// /// This should be used from within a process' message loop only /// </remarks> /// <returns>IDisposable, call IDispose to end the subscription</returns> public static Unit subscribe(ProcessId pid) => InMessageLoop ? ActorContext.SelfProcess.Actor.AddSubscription(pid, ActorContext.Observe <object>(pid).Subscribe(x => tell(Self, x, pid))) : raiseUseInMsgLoopOnlyException <Unit>(nameof(subscribe));
/// <summary> /// Get an IObservable for a process publish stream. When a process calls 'publish' it emits /// messages on the observable returned by this method. /// </summary> /// <remarks> /// The process can publish any number of types, any published messages not of type T will be ignored. /// /// Because this call is asychronous it could allow access to the message loop, therefore /// you can't call it from within a process message loop. /// </remarks> /// <returns>IObservable T</returns> public static IObservable <T> observe <T>(ProcessId pid) => InMessageLoop ? raiseDontUseInMessageLoopException <IObservable <T> >(nameof(observe)) : ActorContext.Observe <T>(pid);