private void ThrowOnNonSuccess(XtResultBase xtResult) { if (xtResult.IsSuccess == false) { throw ZeroMqXtSocketException.FromException(xtResult.Exception); } }
internal static XtResult <TMessage> ParsePubSubMessage <TMessage>(this NetMQMessage msg, SocketConfiguration configuration) where TMessage : class { const string operation = "parse-pub-sub-msg"; if (msg.FrameCount != 2) { var exc = ZeroMqXtSocketException.MissedExpectedFrameCount(msg.FrameCount); configuration.Logger.Log(new DebugLogMsg(exc.Message)); return(XtResult <TMessage> .Failed(ZeroMqXtSocketException.MissedExpectedFrameCount(msg.FrameCount, 2))); } var receivedType = configuration.Serializer.Deserialize <string>(msg.First.ToByteArray()); if (receivedType != typeof(TMessage).FullName) { return(XtResult <TMessage> .Failed(ZeroMqXtSocketException.Frame1TypeDoesNotMatch <TMessage>(receivedType))); } try { var instance = configuration.Serializer.Deserialize <TMessage>(msg.Last.ToByteArray()); return(XtResult <TMessage> .Success(instance, operation : operation)); } catch (System.Exception ex) { return(XtResult <TMessage> .Failed(ex, operation : operation)); } }
///<summary> /// Construct a Message from ReceivedFrames - according to /// <para>Frame 1 - RequestTypeName</para> /// <para>Frame 2 - Successful parsing and use of Incoming Instance of RequestType / on Response it is the successful deserialization</para> /// <para>Frame 3 - Actual Payload and instance of the RequestType</para> ///</summary> internal static XtResult <TMessage> ParseRqRepMessage <TMessage>(this NetMQMessage msg, SocketConfiguration configuration) where TMessage : class { configuration.Logger.Log(new DebugLogMsg($"parsing [{typeof(TMessage)}]")); const string operation = "parse-rq-rep-msg"; #region precondition checks if (msg.FrameCount != 3) { var exc = ZeroMqXtSocketException.MissedExpectedFrameCount(msg.FrameCount); configuration.Logger.Log(new DebugLogMsg(exc.Message)); return(XtResult <TMessage> .Failed(exc, operation)); } byte[] typeFrame = msg.Pop().ToByteArray(); byte[] successFrame = msg.Pop().ToByteArray(); byte[] payloadFrame = msg.Pop().ToByteArray(); string msgType = typeof(TMessage).TypeFrameName(); string typeFromFrame = configuration.Serializer.Deserialize <string>(typeFrame); if (typeFromFrame != msgType) { var exception = ZeroMqXtSocketException.Frame1TypeDoesNotMatch <TMessage>(typeFromFrame); configuration.Logger.Log(new DebugLogMsg(exception.Message)); return(XtResult <TMessage> .Failed(exception, operation)); } bool isSuccess = Convert.ToBoolean(configuration.Serializer.Deserialize <string>(successFrame)); if (!isSuccess) { var exceptnText = configuration.Serializer.Deserialize <string>(payloadFrame); var excption = new ZeroMqXtSocketException("Server failed with" + exceptnText); configuration.Logger.Log(new DebugLogMsg(excption.Message)); return(XtResult <TMessage> .Failed(excption, operation)); } #endregion try { // actual message body deserialization TMessage result = configuration.Serializer.Deserialize <TMessage>(payloadFrame); if (result == default(TMessage)) { return(XtResult <TMessage> .Failed(new ArgumentNullException($"{typeof(TMessage)} yielded the default value on deserializing! Proceeding is not safe."), operation)); } configuration.Logger.Log(new DebugLogMsg($"parsing was successful for [{typeof(TMessage)}]")); return(XtResult <TMessage> .Success(result, operation)); } catch (System.Exception ex) { return(XtResult <TMessage> .Failed(ZeroMqXtSocketException.SerializationFailed(ex.Message), operation)); } }
///<summary> /// necessary indirection for the responsehandler to be used in sync or async fashion ///</summary> private XtResult SetupResponder <T, TResult>(ResponseHandler <T, TResult> handler, CancellationToken token) where T : class, new() where TResult : class { lock (concurrencyToken) { if (responderIsSetup) { throw new ZeroMqXtSocketException("Responder for this instance of Socket exists already. Use a new instance for each server!"); } responderIsSetup = true; respondingIsActive = true; } poller = new NetMQ.NetMQPoller(); responseSocket = new ResponseSocket(); // handle notifies when the server is set up eventHandle = new ManualResetEvent(false); // create a new background thread with the response callback Exception faultingException = null; _ = Task.Run(() => { try { responseSocket.Bind(_configuration.Address()); // add to poller and register handler poller.Add(responseSocket); receiveHandler = async(s, e) => await ResponseHandlerCallback(responseSocket, handler, token); responseSocket.ReceiveReady += receiveHandler; poller.RunAsync(); } catch (Exception exception) { faultingException = exception; _configuration.Logger.Log(new ErrorLogMsg(exception.GetType().Name + "-" + exception.Message)); Dispose(); } finally { // open resetevent after binding to the socket and when the poller is started eventHandle.Set(); } }, token); // wait for the Set inside the background thread so we can know at the calling client that the server is set up properly eventHandle.WaitOne(); return(faultingException == null ? XtResult.Success("setup-response") : XtResult.Failed(ZeroMqXtSocketException.FromException(faultingException), "setup-response")); }