public string WriteFrame(IStompFrame frame) { var sb = StringBuilder; // Команда sb.Append(frame.Command); sb.Append(EOL); // Заголовки var shouldEncode = ShouldUseHeaderEncoding(frame.Command); foreach (var pair in frame.Headers) { var key = pair.Key; foreach (var value in pair.Value) { EncodeValue(sb, key, shouldEncode); sb.Append(SEPARATOR); EncodeValue(sb, value, shouldEncode); sb.Append(EOL); } } sb.Append(EOL); // Тело sb.Append(frame.Body); // Терминатор sb.Append(TERMINATOR); var str = sb.ToString(); sb.Clear(); return(str); }
public static void EnsureMessageHasNoBody(this IStompFrame frame) { if (!string.IsNullOrEmpty(frame.Body)) { throw new StompProtocolException($"Body is not allowed for {frame.Command} frame"); } }
internal Error(IStompFrame frame) { ReceiptId = frame.GetHeader("receipt-id", isRequired: false); Message = frame.GetHeader("message", isRequired: false); // frame.EnsureMessageHasNoBody(); }
public void Send(IStompFrame frame) { try { if (State != StompConnectionState.Connected) { throw new StompConnectionException("STOMP connection is off-line"); } var rawMessage = _wireFormat.WriteFrame(frame); _logger.ClientFrame(rawMessage); _transport.SendMessage(rawMessage); } catch (StompWireFormatException e) { _logger.Error("Protocol error while sending", e); throw; } catch (Exception e) { _logger.Error("Error while sending", e); throw; } }
internal Connected(IStompFrame frame) { Version = frame.GetHeader("version", isRequired: true); Session = frame.GetHeader("session", isRequired: false); Server = frame.GetHeader("server", isRequired: false); Heartbeat = frame.GetHeader("heart-beat", isRequired: false); frame.EnsureMessageHasNoBody(); }
protected override void SendStompFrame(string sessionId, IStompFrame stompFrame) { var client = tcpClients[sessionId]; var stream = client.GetStream(); byte[] message = Encoding.ASCII.GetBytes(stompFrame.Serialize()); stream.Write(message, 0, message.Length); }
internal Message(IStompFrame frame) { Destination = frame.GetHeader("destination", isRequired: true); Subscription = frame.GetHeader("subscription", isRequired: true); MessageId = frame.GetHeader("message-id", isRequired: true); Ask = frame.GetHeader("ask", isRequired: false); frame.GetBody(out var body, out var contentType); Body = body; ContentType = contentType; }
public static string GetHeader(this IStompFrame frame, string name, bool isRequired = false) { if (!frame.Headers.TryGetValue(name, out var value)) { if (isRequired) { throw new StompProtocolException($"\"{name}\" header is required for {frame.Command} frame"); } return(null); } return(value); }
/// <summary> /// Парсинг стакана /// </summary> private void ParseBook(IStompFrame frame, string subscription) { if (!obIdToInstrument.TryGetValue(subscription, out var instrument)) { return; } var json = JObject.Parse(frame.Body); var columns = (JArray)json["columns"]; var allData = (JArray)json["data"]; var ob = new OrderBook(allData.Count) { Instrument = instrument }; var ip = GetInstrumentParams(instrument); OrderBookItem prev = null, curr; for (var i = allData.Count - 1; i >= 0; i--) { var data = (JArray)allData[i]; var dict = new JArrayDictionary(columns, data); ob.Items.Add(curr = new OrderBookItem { Operation = dict["BUYSELL"].ToString() == "B" ? OrderOperation.Buy : OrderOperation.Sell, Price = (decimal)dict["PRICE"][0], Quantity = (int)dict["QUANTITY"], }); if (prev?.Operation == OrderOperation.Sell && curr.Operation == OrderOperation.Buy) { ip.BestOfferPrice = prev.Price; ip.BestOfferQuantity = prev.Quantity; ip.BestBidPrice = curr.Price; ip.BestBidQuantity = curr.Quantity; } prev = curr; } OnMessageReceived(ip); OnMessageReceived(ob); }
internal static ServerMessage Read(IStompFrame frame) { switch (frame.Command) { case StompCommands.CONNECTED: return(new Connected(frame)); case StompCommands.RECEIPT: return(new Receipt(frame)); case StompCommands.MESSAGE: return(new Message(frame)); case StompCommands.ERROR: return(new Error(frame)); default: throw new StompProtocolException($"Unknwon server frame: {frame.Command}"); } }
/// <summary> /// Парсинг параметров /// </summary> private void ParseParams(IStompFrame frame, string subscription) { if (!ipIdToInstrument.TryGetValue(subscription, out var instrument)) { return; } var json = JObject.Parse(frame.Body); var columns = (JArray)json["columns"]; var allData = (JArray)json["data"]; foreach (JArray data in allData) { var dict = new JArrayDictionary(columns, data); //var ticker = dict["TICKER"].ToString(); var ip = GetInstrumentParams(instrument); ip.LastPrice = (decimal)dict["LAST"][0]; ip.BestBidPrice = (decimal)dict["BID"][0]; ip.BestOfferPrice = (decimal)dict["OFFER"][0]; //ip.Settlement = (decimal) dict["WAPRICE"][0]; //foreach (var kvp in dict) //{ // switch (kvp.Key) // { // case "LAST": // ip.LastPrice = (decimal)kvp.Value[0]; // break; // case "BID": // ip.BestBidPrice = (decimal)kvp.Value[0]; // break; // //case "BIDDEPTHT": // // ip.BestBidQuantity = (int)kvp.Value; // // break; // case "OFFER": // ip.BestOfferPrice = (decimal)kvp.Value[0]; // break; // //case "OFFERDEPTHT": // // ip.BestOfferQuantity = (int)kvp.Value; // // break; // case "WAPRICE": // ip.Settlement = (decimal)kvp.Value[0]; // break; // case "PREVPRICE": // ip.PreviousSettlement = (decimal)kvp.Value[0]; // break; // default: // break; // } //} OnMessageReceived(ip); } }
protected override void SendStompFrame(string sessionId, IStompFrame stompFrame) { var websocketConnection = this.clients[sessionId]; websocketConnection.Send(stompFrame.Serialize()); }
protected abstract void SendStompFrame(IStompFrame stompFrame);
private void OnMessageReceived(IStompFrame frame) => MessageReceived?.Invoke(this, new StompMessageReceivedEventArgs(frame));
public static void GetBody(this IStompFrame frame, out string body, out string contentType) { contentType = frame.GetHeader("content-type") ?? "application/octet-stream"; body = frame.Body; }
protected override void SendStompFrame(IStompFrame stompFrame) { var serializedStompFrame = stompFrame.Serialize(); this.websocket.Send(serializedStompFrame); }
private void OnWebsocketMessageReceived(object sender, WebSocket4Net.MessageReceivedEventArgs e) { if (e.Message == "\r\n" || e.Message == "\n") { Log.Trace("EOL received"); this.StompHeartbeatReceiveTimer?.Stop(); this.StompHeartbeatReceiveTimer?.Start(); return; } Log.Info($"Websocket message received: {e.Message}"); var stompFrame = IStompFrame.Deserialize(e.Message); switch (stompFrame) { case ConnectedFrame frame: if (frame.ServerExpectedHeartbeatInterval.TotalMilliseconds != 0) { this.StompHeartbeatSendTimer = new System.Timers.Timer(frame.ServerExpectedHeartbeatInterval.TotalMilliseconds); this.StompHeartbeatSendTimer.Elapsed += this.HeartbeatSendTimerElapsed; this.StompHeartbeatSendTimer.Start(); } if (frame.ServerSendingHeartbeatInterval.TotalMilliseconds != 0) { this.StompHeartbeatReceiveTimer = new System.Timers.Timer((this.StompHeartbeatIntervalFromServerToClient + this.StompHeartbeatTimeout).TotalMilliseconds); this.StompHeartbeatReceiveTimer.Elapsed += this.HeartbeatReceivedTimerElapsed; this.StompHeartbeatReceiveTimer.Start(); } this.InvokeConnectedEvent(new ConnectedEventArgs(frame)); break; case ErrorFrame frame: this.InvokeErrorReceivedEvent(new ErrorReceivedEventArgs(frame)); break; case ReceiptFrame frame: this.InvokeReceiptReceivedEvent(new ReceiptReceivedEventArgs(frame)); break; case MessageFrame frame: var eventArguments = new EventArguments.MessageReceivedEventArgs(frame); if (this.subscriptionCallbacks.ContainsKey(frame.Headers.Destination)) { var parameters = new object[] { this, eventArguments, }; this.subscriptionCallbacks[frame.Headers.Destination].DynamicInvoke(parameters); } else { this.InvokeMessageReceivedEvent(eventArguments); } break; default: Log.Info($"Unkown stomp frame: {stompFrame.Body}"); break; } this.StompHeartbeatReceiveTimer?.Stop(); this.StompHeartbeatReceiveTimer?.Start(); }
public StompMessageReceivedEventArgs(IStompFrame frame) { Message = frame; }
public void ProcessMessage(string sessionId, string messageString) { if (messageString == "\r\n") { Log.Trace("EOL received"); if (this.sessionIdToHeartbeatReceivedTimers.ContainsKey(sessionId)) { var heartbeatReceiveTimerToResett = this.sessionIdToHeartbeatReceivedTimers[sessionId]; heartbeatReceiveTimerToResett.Stop(); heartbeatReceiveTimerToResett.Start(); } return; } Log.Debug($"Message received from client '{sessionId}': {messageString}"); var stompFrame = IStompFrame.Deserialize(messageString); switch (stompFrame) { case ConnectFrame frame: var version = "1.2"; var connectedFrame = new ConnectedFrame(version) { Headers = new ConnectedFrameHeaders() { Version = version, Session = sessionId, Server = "Stomp4Net/1.0.0", Heartbeat = $"{this.StompHeartbeatIntervalFromServerToClient.TotalMilliseconds},{this.StompHeartbeatIntervalFromClientToServer.TotalMilliseconds}", }, }; if (frame.ClientExpectedHeartbeatInterval.TotalMilliseconds != 0) { var heartbeatSendTimer = new Timer(this.StompHeartbeatIntervalFromServerToClient.TotalMilliseconds); heartbeatSendTimer.Elapsed += this.SendHeartbeatTimerElapsed; heartbeatSendTimer.Start(); this.sessionIdToHeartbeatSendTimers.Add(sessionId, heartbeatSendTimer); this.heartbeatSendTimersToSessionId.Add(heartbeatSendTimer, sessionId); } if (frame.ClientExpectedHeartbeatInterval.TotalMilliseconds != 0) { var heartbeatReceiveTimer = new Timer( (this.StompHeartbeatIntervalFromServerToClient + this.StompHeartbeatTimeout).TotalMilliseconds); heartbeatReceiveTimer.Elapsed += this.ReceiveHeartbeatTimerElapsed; heartbeatReceiveTimer.Start(); this.sessionIdToHeartbeatReceivedTimers.Add(sessionId, heartbeatReceiveTimer); this.heartbeatReceivedTimersToSessionId.Add(heartbeatReceiveTimer, sessionId); } this.SendStompFrame(sessionId, connectedFrame); this.ClientConnected?.Invoke(this, new ClientConnectedEventArgs(sessionId)); break; case StompFrame frame: version = "1.2"; connectedFrame = new ConnectedFrame(version) { Headers = new ConnectedFrameHeaders() { Version = version, Session = sessionId, Server = "Stomp4Net/1.0.0", Heartbeat = $"{this.StompHeartbeatIntervalFromServerToClient.TotalMilliseconds},{this.StompHeartbeatIntervalFromClientToServer.TotalMilliseconds}", }, }; if (frame.ClientExpectedHeartbeatInterval.TotalMilliseconds != 0) { var heartbeatSendTimer = new Timer(this.StompHeartbeatIntervalFromServerToClient.TotalMilliseconds); heartbeatSendTimer.Elapsed += this.SendHeartbeatTimerElapsed; heartbeatSendTimer.Start(); this.sessionIdToHeartbeatSendTimers.Add(sessionId, heartbeatSendTimer); this.heartbeatSendTimersToSessionId.Add(heartbeatSendTimer, sessionId); } if (frame.ClientExpectedHeartbeatInterval.TotalMilliseconds != 0) { var heartbeatReceiveTimer = new Timer( (this.StompHeartbeatIntervalFromServerToClient + this.StompHeartbeatTimeout).TotalMilliseconds); heartbeatReceiveTimer.Elapsed += this.ReceiveHeartbeatTimerElapsed; heartbeatReceiveTimer.Start(); this.sessionIdToHeartbeatReceivedTimers.Add(sessionId, heartbeatReceiveTimer); this.heartbeatReceivedTimersToSessionId.Add(heartbeatReceiveTimer, sessionId); } this.SendStompFrame(sessionId, connectedFrame); this.ClientConnected?.Invoke(this, new ClientConnectedEventArgs(sessionId)); break; case SendFrame frame: var eventArguments = new EventArguments.SendReceivedEventArgs(sessionId, frame); if (this.notificationForDestinationCallbacks.ContainsKey(frame.Headers.Destination)) { var parameters = new object[] { this, eventArguments, }; this.notificationForDestinationCallbacks[frame.Headers.Destination].DynamicInvoke(parameters); } else { this.SendReceived?.Invoke( this, eventArguments); } if (this.stompSubscriptions.ContainsKey(frame.Headers.Destination)) { var subscriptionsToNotify = this.stompSubscriptions[frame.Headers.Destination]; foreach (var subscriptionToNotify in subscriptionsToNotify) { var messageFrame = new MessageFrame(frame.Headers.Destination, subscriptionToNotify.Id, frame.Body, frame.Headers.ContentType); this.SendStompFrame(subscriptionToNotify.SessionId, messageFrame); } } break; case SubscribeFrame frame: List <StompSubscription> stompSubscriptionsForDestination; if (this.stompSubscriptions.ContainsKey(frame.Headers.Id)) { stompSubscriptionsForDestination = this.stompSubscriptions[frame.Headers.Destination]; } else { stompSubscriptionsForDestination = new List <StompSubscription>(); } stompSubscriptionsForDestination.Add(new StompSubscription(frame.Headers.Id, sessionId)); this.stompSubscriptions[frame.Headers.Destination] = stompSubscriptionsForDestination; break; case DisconnectFrame frame: this.ClientDisconnected?.Invoke(this, new ClientDisconnectedEventArgs(sessionId)); break; default: Log.Warn($"Unkown frame: {messageString}"); break; } if (this.sessionIdToHeartbeatReceivedTimers.ContainsKey(sessionId)) { var heartbeatReceiveTimerToReset = this.sessionIdToHeartbeatReceivedTimers[sessionId]; heartbeatReceiveTimerToReset.Stop(); heartbeatReceiveTimerToReset.Start(); } }
internal Receipt(IStompFrame frame) { ReceiptId = frame.GetHeader("receipt-id", isRequired: true); frame.EnsureMessageHasNoBody(); }
protected abstract void SendStompFrame(string sessionId, IStompFrame stompFrame);