/// <summary> /// Отправить исходящее сообщение, вызвав событие <see cref="NewOutMessage"/>. /// </summary> /// <param name="message">Сообщение.</param> public virtual void SendOutMessage(Message message) { InitMessageLocalTime(message); switch (message.Type) { case MessageTypes.Security: { NewOutMessage.SafeInvoke(message); if (!CreateAssociatedSecurity) { break; } var clone = (SecurityMessage)message.Clone(); clone.SecurityId = CloneSecurityId(clone.SecurityId); NewOutMessage.SafeInvoke(clone); break; } case MessageTypes.Level1Change: { NewOutMessage.SafeInvoke(message); var l1Msg = (Level1ChangeMessage)message; if (l1Msg.SecurityId.IsDefault()) { break; } if (CreateAssociatedSecurity) { // обновление BestXXX для ALL из конкретных тикеров var clone = (Level1ChangeMessage)l1Msg.Clone(); clone.SecurityId = CloneSecurityId(clone.SecurityId); NewOutMessage.SafeInvoke(clone); } if (CreateDepthFromLevel1) { // генерация стакана из Level1 var builder = _level1DepthBuilders.SafeAdd(l1Msg.SecurityId, c => new Level1DepthBuilder(c)); if (builder.Process(l1Msg)) { var quoteMsg = builder.QuoteChange; NewOutMessage.SafeInvoke(quoteMsg); CreateAssociatedSecurityQuotes(quoteMsg); } } break; } case MessageTypes.QuoteChange: { var quoteMsg = (QuoteChangeMessage)message; NewOutMessage.SafeInvoke(quoteMsg); if (CreateDepthFromLevel1) { _level1DepthBuilders.SafeAdd(quoteMsg.SecurityId, c => new Level1DepthBuilder(c)).HasDepth = true; } CreateAssociatedSecurityQuotes(quoteMsg); break; } case MessageTypes.Execution: { NewOutMessage.SafeInvoke(message); if (!CreateAssociatedSecurity) { break; } var execMsg = (ExecutionMessage)message; if (execMsg.SecurityId.IsDefault()) { break; } switch (execMsg.ExecutionType) { case ExecutionTypes.Tick: case ExecutionTypes.OrderLog: { var clone = (ExecutionMessage)message.Clone(); clone.SecurityId = CloneSecurityId(clone.SecurityId); NewOutMessage.SafeInvoke(clone); break; } } break; } default: { if (_prevTime != DateTime.MinValue) { var diff = message.LocalTime - _prevTime; //if (message.Type != MessageTypes.Time && diff >= MarketTimeChangedInterval) //{ // SendOutMessage(new TimeMessage // { // LocalTime = message.LocalTime, // ServerTime = message.GetServerTime(), // }); //} _secLookupTimeOut .ProcessTime(diff) .ForEach(id => SendOutMessage(new SecurityLookupResultMessage { OriginalTransactionId = id })); _pfLookupTimeOut .ProcessTime(diff) .ForEach(id => SendOutMessage(new PortfolioLookupResultMessage { OriginalTransactionId = id })); //ProcessReconnection(diff); } _prevTime = message.LocalTime; NewOutMessage.SafeInvoke(message); break; } } }
/// <summary> /// Send incoming message. /// </summary> /// <param name="message">Message.</param> public void SendInMessage(Message message) { if (message.Type == MessageTypes.Connect) { if (!Platform.IsCompatible()) { SendOutMessage(new ConnectMessage { Error = new InvalidOperationException(LocalizedStrings.Str169Params.Put(GetType().Name, Platform)) }); return; } } InitMessageLocalTime(message); switch (message.Type) { case MessageTypes.PortfolioLookup: { if (!IsSupportNativePortfolioLookup) { _pfLookupTimeOut.StartTimeOut(((PortfolioLookupMessage)message).TransactionId); } break; } case MessageTypes.SecurityLookup: { if (!IsSupportNativeSecurityLookup) { _secLookupTimeOut.StartTimeOut(((SecurityLookupMessage)message).TransactionId); } break; } } try { OnSendInMessage(message); } catch (Exception ex) { this.AddErrorLog(ex); switch (message.Type) { case MessageTypes.Connect: SendOutMessage(new ConnectMessage { Error = ex }); return; case MessageTypes.Disconnect: SendOutMessage(new DisconnectMessage { Error = ex }); return; case MessageTypes.OrderRegister: case MessageTypes.OrderReplace: case MessageTypes.OrderCancel: case MessageTypes.OrderGroupCancel: { var replyMsg = ((OrderMessage)message).CreateReply(); SendOutErrorExecution(replyMsg, ex); return; } case MessageTypes.OrderPairReplace: { var replyMsg = ((OrderPairReplaceMessage)message).Message1.CreateReply(); SendOutErrorExecution(replyMsg, ex); return; } case MessageTypes.MarketData: { var reply = (MarketDataMessage)message.Clone(); reply.OriginalTransactionId = reply.TransactionId; reply.Error = ex; SendOutMessage(reply); return; } case MessageTypes.SecurityLookup: { var lookupMsg = (SecurityLookupMessage)message; SendOutMessage(new SecurityLookupResultMessage { OriginalTransactionId = lookupMsg.TransactionId, Error = ex }); return; } case MessageTypes.PortfolioLookup: { var lookupMsg = (PortfolioLookupMessage)message; SendOutMessage(new PortfolioLookupResultMessage { OriginalTransactionId = lookupMsg.TransactionId, Error = ex }); return; } case MessageTypes.ChangePassword: { var pwdMsg = (ChangePasswordMessage)message; SendOutMessage(new ChangePasswordMessage { OriginalTransactionId = pwdMsg.TransactionId, Error = ex }); return; } } SendOutError(ex); } }
/// <summary> /// Отправить входящее сообщение. /// </summary> /// <param name="message">Сообщение.</param> public void SendInMessage(Message message) { //if (!CheckLicense(message)) // return; if (message.Type == MessageTypes.Connect) { if (!Platform.IsCompatible()) { SendOutMessage(new ConnectMessage { Error = new InvalidOperationException(LocalizedStrings.Str169Params.Put(GetType().Name, Platform)) }); return; } } #warning force //месседжи с заявками могут складываться из потока обработки var force = message.Type == MessageTypes.OrderRegister || message.Type == MessageTypes.OrderReplace || message.Type == MessageTypes.OrderPairReplace || message.Type == MessageTypes.OrderCancel || message.Type == MessageTypes.OrderGroupCancel; InitMessageLocalTime(message); // при отключенном состоянии пропускаем только TimeMessage // остальные типы сообщений могут использоваться (например, в эмуляторе) //if ((_currState == ConnectionStates.Disconnecting || _currState == ConnectionStates.Disconnected) && message.Type == MessageTypes.Time) // return; switch (message.Type) { case MessageTypes.PortfolioLookup: { if (!IsSupportNativePortfolioLookup) { _pfLookupTimeOut.StartTimeOut(((PortfolioLookupMessage)message).TransactionId); } break; } case MessageTypes.SecurityLookup: { if (!IsSupportNativeSecurityLookup) { _secLookupTimeOut.StartTimeOut(((SecurityLookupMessage)message).TransactionId); } break; } } try { OnSendInMessage(message); } catch (Exception ex) { this.AddErrorLog(ex); switch (message.Type) { case MessageTypes.Connect: SendOutMessage(new ConnectMessage { Error = ex }); return; case MessageTypes.Disconnect: SendOutMessage(new DisconnectMessage { Error = ex }); return; case MessageTypes.OrderRegister: { var execMsg = ((OrderRegisterMessage)message).ToExecutionMessage(); execMsg.Error = ex; execMsg.OrderState = OrderStates.Failed; SendOutMessage(execMsg); return; } case MessageTypes.OrderReplace: { var execMsg = ((OrderReplaceMessage)message).ToExecutionMessage(); execMsg.Error = ex; execMsg.OrderState = OrderStates.Failed; SendOutMessage(execMsg); return; } case MessageTypes.OrderPairReplace: { var execMsg = ((OrderPairReplaceMessage)message).ToExecutionMessage(); execMsg.Error = ex; execMsg.OrderState = OrderStates.Failed; SendOutMessage(execMsg); return; } case MessageTypes.OrderCancel: { var execMsg = ((OrderCancelMessage)message).ToExecutionMessage(); execMsg.Error = ex; execMsg.OrderState = OrderStates.Failed; SendOutMessage(execMsg); return; } case MessageTypes.OrderGroupCancel: { var execMsg = ((OrderGroupCancelMessage)message).ToExecutionMessage(); execMsg.Error = ex; execMsg.OrderState = OrderStates.Failed; SendOutMessage(execMsg); return; } case MessageTypes.MarketData: { var reply = (MarketDataMessage)message.Clone(); reply.OriginalTransactionId = reply.TransactionId; reply.Error = ex; SendOutMessage(reply); return; } case MessageTypes.SecurityLookup: { var lookupMsg = (SecurityLookupMessage)message; SendOutMessage(new SecurityLookupResultMessage { OriginalTransactionId = lookupMsg.TransactionId, Error = ex }); return; } case MessageTypes.PortfolioLookup: { var lookupMsg = (PortfolioLookupMessage)message; SendOutMessage(new PortfolioLookupResultMessage { OriginalTransactionId = lookupMsg.TransactionId, Error = ex }); return; } case MessageTypes.ChangePassword: { var pwdMsg = (ChangePasswordMessage)message; SendOutMessage(new ChangePasswordMessage { OriginalTransactionId = pwdMsg.TransactionId, Error = ex }); return; } } SendOutError(ex); } if (message.IsBack) { message.IsBack = false; // time msg should be return back SendOutMessage(message); } }