/// <summary> /// A Message receive callback delegate that prints the SDT content /// of received messages. /// </summary> /// <param name="source"></param> /// <param name="args"></param> public void PrintReceivedMessage(Object source, MessageEventArgs args) { IMessage message = args.Message; ISDTContainer container = SDTUtils.GetContainer(message); StringBuilder sb = new StringBuilder(); if (container is IMapContainer) { IMapContainer map = (IMapContainer)container; sb.Append("map={"); while (map.HasNext()) { KeyValuePair <string, ISDTField> entry = map.GetNext(); sb.Append(string.Format("\n\tkey={0} value={1}", entry.Key, entry.Value.Value.ToString())); } sb.Append("}\n"); } else if (container is IStreamContainer) { IStreamContainer stream = (IStreamContainer)container; sb.Append("stream={"); while (stream.HasNext()) { ISDTField entry = stream.GetNext(); sb.Append(string.Format("\n\tvalue={0}", entry.Value.ToString())); } sb.Append("}\n"); } SampleUtils.HandleMessageEvent(source, args); Console.WriteLine(sb.ToString()); }
/// <summary> /// Message event callback, this is where we handle message requests /// </summary> /// <param name="source"></param> /// <param name="args"></param> private void HandleRequestMessage(Object source, MessageEventArgs args) { // Received a request message IMessage requestMessage = args.Message; Console.WriteLine("\nReceived request message, trying to parse it"); // Parse it ISDTContainer sdt_data = SDTUtils.GetContainer(requestMessage); if (sdt_data is IStreamContainer) { IStreamContainer sdt_stream = (IStreamContainer)sdt_data; ISDTField operation = sdt_stream.GetNext(); if (operation != null && operation.Type == SDTFieldType.INT8) { ISDTField leftOperand = sdt_stream.GetNext(); if (leftOperand != null && leftOperand.Type == SDTFieldType.INT32) { ISDTField rightOperand = sdt_stream.GetNext(); if (rightOperand != null && rightOperand.Type == SDTFieldType.INT32) { int enumVal = Int32.Parse(operation.Value.ToString()); Operation op = (Operation)enumVal; Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand.Value, op, rightOperand.Value, "?"); IMessage replyMessage = ProcessArithmeticExpression((short)operation.Value, (Int32)leftOperand.Value, (Int32)rightOperand.Value); try { Console.WriteLine("Sending replyMessage to requester..."); replyMessage.Destination = requestMessage.ReplyTo; session.Send(replyMessage); Console.WriteLine("Listening for request messages ... Press any key(except for Ctrl+C) to exit"); return; } catch (Exception ex) { PrintException(ex); return; } finally { requestMessage.Dispose(); replyMessage.Dispose(); } } } } } // If we reach this point, the message format is not expected. Console.WriteLine("Failed to parse the request message, here's a message dump:\n{0}", requestMessage.Dump()); requestMessage.Dispose(); /* A good practice*/ }
private void doRequest(Operation operation, int leftOperand, int rightOperand) { // Create the request message IMessage requestMessage = ContextFactory.Instance.CreateMessage(); requestMessage.Destination = ContextFactory.Instance.CreateTopic(requestTopicStr); requestMessage.DeliveryMode = MessageDeliveryMode.Direct; /* explicitly set to MessageDeliveryMode.Direct */ IStreamContainer stream = SDTUtils.CreateStream(requestMessage, 256); stream.AddInt8((short)operation); stream.AddInt32(leftOperand); stream.AddInt32(rightOperand); // Send the request message to the service or RRDirectReplier IMessage replyMessage = null; int timeout = 2000; /* 2 secs*/ Console.WriteLine("\nSending request message, waiting for {0} msecs for a reply (make sure that RRDirectReply is running) ...", timeout); Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand, operation.ToString(), rightOperand, "?"); if (session.SendRequest(requestMessage, out replyMessage, 2000) == ReturnCode.SOLCLIENT_OK) { // Got a reply, format and print the response message Console.WriteLine("\nGot reply message"); IStreamContainer respStream = (IStreamContainer)SDTUtils.GetContainer(replyMessage); if (respStream != null) { ISDTField status = respStream.GetNext(); if (status.Type == SDTFieldType.BOOL) { if (((bool)status.Value)) { Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand, operation.ToString(), rightOperand, respStream.GetNext().Value.ToString()); } else { Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand, operation.ToString(), rightOperand, "operation failed"); } } } } else { Console.WriteLine("Request failed"); } if (requestMessage != null) { // It is a good practice to dispose of messages once done using them requestMessage.Dispose(); } }
public void Convert(IMessage from, Message to) { var streamContainer = SDTUtils.GetContainer(from) as IStreamContainer; if (streamContainer != null) { using (streamContainer) { var list = new List <object>(); while (streamContainer.HasNext()) { list.Add(streamContainer.GetNext().Value); } if (list.Count > 0) { to.Properties["SdtStreamContainer"] = list; } } } }
/// <summary> /// Computes the results and stores it in a reply message /// </summary> /// <param name="operation"></param> /// <param name="leftOperand"></param> /// <param name="rightOperand"></param> /// <returns></returns> private IMessage ProcessArithmeticExpression(short operation, Int32 leftOperand, Int32 rightOperand) { // Create the reply message IMessage replyMessage = ContextFactory.Instance.CreateMessage(); replyMessage.DeliveryMode = MessageDeliveryMode.Direct; IStreamContainer stream = SDTUtils.CreateStream(replyMessage, 256); double? result = null; try { switch ((int)operation) { case (int)Operation.DIVIDE: result = (double)((double)leftOperand / (double)rightOperand); break; case (int)Operation.MINUS: result = (double)(leftOperand - rightOperand); break; case (int)Operation.PLUS: result = (double)(leftOperand + rightOperand); break; case (int)Operation.TIMES: result = (double)(leftOperand * rightOperand); break; default: result = null; break; } if (result == null) { stream.AddBool(false); } else { double val = result.Value; if (double.IsNaN(val) || double.IsInfinity(val)) { stream.AddBool(false); } else { stream.AddBool(true); stream.AddDouble(val); } } } catch (Exception) { stream.Rewind(); stream.AddBool(false); } Operation opEnum = (Operation)((int)operation); if (Enum.IsDefined(typeof(Operation), (Int32)operation)) { Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand, opEnum, rightOperand, (result == null ? "operation failed" : result.ToString())); } else { Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand, "UNKNOWN", rightOperand, (result == null ? "operation failed" : result.ToString())); } return(replyMessage); }
private void HandleMessageEvent(Object source, MessageEventArgs args) { using (IMessage requestMsg = args.Message) { try { string requestJSON = Encoding.ASCII.GetString(requestMsg.BinaryAttachment); log.DebugFormat("OrderRequest Received. Topic: {0} - Contents: {1}", requestMsg.Destination.Name, requestJSON); OrderRequest request = JsonConvert.DeserializeObject <OrderRequest>(requestJSON); #region create settlement message IMessage settlementMsg = ContextFactory.Instance.CreateMessage(); settlementMsg.Destination = ContextFactory.Instance.CreateTopic(_config.ExchSettlementTopicPrefix + request.settlementExch + "/" + request.account + "/" + request.instrument); Settlement settlement = new Settlement(request); settlement.executionExch = _config.ExchName; string settlementJSON = JsonConvert.SerializeObject(settlement); //settlementMsg.BinaryAttachment = Encoding.ASCII.GetBytes(settlementJSON); SDTUtils.SetText(settlementMsg, settlementJSON); log.DebugFormat("Publishing Settlement message. Topic: {0} - Contents: {1}", settlementMsg.Destination.Name, settlementJSON); SendMessage(settlementMsg); #endregion #region create MD trade message Trade trade = new Trade(request); IMessage tradeMsg = ContextFactory.Instance.CreateMessage(); tradeMsg.Destination = ContextFactory.Instance.CreateTopic(_config.ExchTradeTopicPrefix + trade.Sec + "/TRADES"); string tradeJSON = "[" + JsonConvert.SerializeObject(trade) + "]"; tradeMsg.BinaryAttachment = Encoding.ASCII.GetBytes(tradeJSON); log.DebugFormat("Publishing Trade message. Topic: {0} - Contents: {1}", tradeMsg.Destination.Name, tradeJSON); SendMessage(tradeMsg); #endregion #region create OrderRequest Response OrderResponse response = new OrderResponse(request); response.executionExch = _config.ExchName; response.orderId = _config.ExchName + "_" + DateTime.Now.ToString("yyyyMMdd") + "_" + (sequenceNumber++).ToString().PadLeft(10, '0'); //Prepare Response for OrderRequest message by reusing the Request message string responseJSON = JsonConvert.SerializeObject(response); requestMsg.BinaryAttachment = Encoding.ASCII.GetBytes(responseJSON); requestMsg.Destination = ContextFactory.Instance.CreateTopic(_config.ExchOrdResponseTopic + response.account + "/" + response.instrument); log.DebugFormat("Publishing Response message. Topic: {0} - Contents: {1}", requestMsg.Destination.Name, responseJSON); SendMessage(requestMsg); #endregion settlementMsg.Dispose(); requestMsg.Dispose(); } catch (Exception e) { log.ErrorFormat("Error", e); } } }
private void doRequest(IDestination requestDestination, IDestination replyToQueue, Operation operation, int leftOperand, int rightOperand) { // Create the request message IMessage requestMessage = ContextFactory.Instance.CreateMessage(); requestMessage.Destination = requestDestination; requestMessage.DeliveryMode = MessageDeliveryMode.Persistent; requestMessage.ReplyTo = replyToQueue; IStreamContainer stream = SDTUtils.CreateStream(requestMessage, 256); stream.AddInt8((short)operation); stream.AddInt32(leftOperand); stream.AddInt32(rightOperand); // Send the request message to the service or RRDirectReplier int timeout = 2000; /* 2 secs*/ Console.WriteLine("\nSending request message, waiting for {0} msecs for a reply (make sure that RRGuaranteedReplier is running) ...", timeout); session.Send(requestMessage); Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand, operation.ToString(), rightOperand, "?"); if (waitForReply.WaitOne(timeout)) { // Got a reply, format and print the response message Console.WriteLine("\nGot reply message"); IStreamContainer respStream = (IStreamContainer)SDTUtils.GetContainer(replyMessage); if (respStream != null) { ISDTField status = respStream.GetNext(); if (status.Type == SDTFieldType.BOOL) { if (((bool)status.Value)) { Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand, operation.ToString(), rightOperand, respStream.GetNext().Value.ToString()); } else { Console.WriteLine(ARITHMETIC_EXPRESSION, leftOperand, operation.ToString(), rightOperand, "operation failed"); } } else { Console.WriteLine("Failed to parse the request message, here's a message dump:\n{0}", replyMessage.Dump()); } } else { Console.WriteLine("Failed to parse the request message, here's a message dump:\n{0}", replyMessage.Dump()); } } else { Console.WriteLine(string.Format("Failed to receive a reply within {0} msecs", timeout)); } // It is a good practice to dispose of messages once done using them if (requestMessage != null) { requestMessage.Dispose(); } if (replyMessage != null) { replyMessage.Dispose(); } }
/// <summary> /// The main function in the sample. /// </summary> /// <param name="args"></param> public override void SampleCall(string[] args) { #region Parse Arguments ArgParser cmdLineParser = new ArgParser(); if (!cmdLineParser.Parse(args)) { // parse failed PrintUsage(INVALID_ARGUMENTS_ERROR); return; } #endregion #region Initialize properties from command line // Initialize the properties. ContextProperties contextProps = new ContextProperties(); SessionProperties sessionProps = SampleUtils.NewSessionPropertiesFromConfig(cmdLineParser.Config); #endregion // Define IContext and ISession and ITopic. IContext context = null; ISession session = null; ITopic topic = null; try { InitContext(cmdLineParser.LogLevel); Console.WriteLine("About to create the Context ..."); context = ContextFactory.Instance.CreateContext(contextProps, null); Console.WriteLine("Context successfully created. "); Console.WriteLine("About to create the Session ..."); session = context.CreateSession(sessionProps, PrintReceivedMessage, SampleUtils.HandleSessionEvent); Console.WriteLine("Session successfully created."); Console.WriteLine("About to connect the Session ..."); if (session.Connect() == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected"); Console.WriteLine(GetRouterInfo(session)); } topic = ContextFactory.Instance.CreateTopic(SampleUtils.SAMPLE_TOPIC); Console.WriteLine("About to subscribe to topic " + SampleUtils.SAMPLE_TOPIC); if (session.Subscribe(topic, true) == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Successfully added topic subscription"); } // Create the message independent stream. IStreamContainer stream = SDTUtils.CreateStream(1024); // Populate the stream. stream.AddDouble(3.141592654); stream.AddString("message"); // Create the message-independent map. IMapContainer map = SDTUtils.CreateMap(1024); // Add a well known integer to the map. map.AddInt32("mersenne", 43112609); // Create the message. IMessage message = ContextFactory.Instance.CreateMessage(); // Set the message delivery options. message.DeliveryMode = MessageDeliveryMode.Direct; message.Destination = topic; int numMsgsToSend = 10; Console.WriteLine(string.Format("About to send {0} messages ...", numMsgsToSend)); for (int i = 0; i < numMsgsToSend; i++) { // Overwrite the "message" field, set the container, and send. map.DeleteField("message"); map.AddString("message", "message" + (i + 1)); // Set the user property map to the map. message.UserPropertyMap = map; SDTUtils.SetSDTContainer(message, stream); session.Send(message); } // Dispose of the map, stream, and message. map.Dispose(); stream.Dispose(); message.Dispose(); Thread.Sleep(500); // wait for 0.5 seconds Console.WriteLine("\nDone"); } catch (Exception ex) { PrintException(ex); } finally { if (session != null) { if (topic != null) { session.Unsubscribe(topic, true); } session.Dispose(); } if (context != null) { context.Dispose(); } // Must cleanup after. CleanupContext(); } }