public ServerSideSubscription(ServerSideSession session, string subscriptionId, MessageQueue messageQueue, string ack) { Session = Verify.ArgumentNotNull(session, "session"); SubscriptionId = Verify.ArgumentNotNull(subscriptionId, "subscriptionId"); MessageQueue = Verify.ArgumentNotNull(messageQueue, "messageQueue"); MessageQueue.AddSubscription(this); AutoAcknowledge = ack == StompAck.Auto; MessageQueue.MessageReceived += MessageQueueMessageReceived; MessageQueue.MessagePublished += MessageQueueMessagePublished; }
public void EndSession(ServerSideSession session) { if (session != null) { using (_lockObject.Lock()) { _sessions.Remove(session.SessionId); session.Dispose(); } } }
private void Connected(StompFrame frame) { using (_lockObject.Lock()) { StartIncomingHeartBeatTimer(); if (frame.IsHeartBeat) { // nothing else to do } else if (frame.Command == StompCommand.Disconnect) { DisconnectWithoutLocking(); var keepSession = frame.GetBoolean(StompHeader.NonStandard.KeepSession, false); if (!keepSession) { _serverData.EndSession(_session); } _session = null; } else { try { // ReSharper disable PossibleNullReferenceException _session.ProcessFrame(frame); // ReSharper restore PossibleNullReferenceException } catch (Exception ex) { if (ex.IsCorruptedStateException()) { throw; } Log.Error(_logMessagePrefix + "Unexpected error handling " + frame.Command + " frame: " + ex.Message, ex); try { var errorFrame = StompFrameUtils.CreateErrorFrame("internal server error", frame); _transport.SendFrame(errorFrame); DisconnectWithoutLocking(); } catch (InvalidOperationException) { // Not ideal, but we can encounter a situation where the transport is shutting down, so if // we send anything it is going to throw and exception. Because we currently do not have an // API for checking this, we just handle the exception. } } } } }
public ServerSideSession CreateSession() { using (_lockObject.Lock()) { var session = new ServerSideSession(this); _sessions.Add(session.SessionId, session); return session; } }
// ReSharper restore UnusedParameter.Local // ReSharper restore MemberCanBeMadeStatic.Local private void ExpectingConnect(StompFrame frame) { if (frame.Command != StompCommand.Connect && frame.Command != StompCommand.Stomp) { string message = "Expecting " + StompCommand.Connected + " or " + StompCommand.Stomp + " command, received " + frame.Command; Log.Error(_logMessagePrefix + message); var errorFrame = StompFrameUtils.CreateErrorFrame(message); _transport.SendFrame(errorFrame); DisconnectWithoutLocking(); return; } var login = frame.Headers[StompHeader.Login]; var passcode = frame.Headers[StompHeader.Passcode]; if (!Authenticate(login, passcode)) { string message = "Received " + frame.Command + " frame, Access denied"; Log.Warn(_logMessagePrefix + message); var errorFrame = StompFrameUtils.CreateErrorFrame(message); _transport.SendFrame(errorFrame); DisconnectWithoutLocking(); return; } Log.Debug(_logMessagePrefix + "Received " + frame.Command + " frame, authenticated OK"); var sessionId = frame.Headers[StompHeader.Session]; ServerSideSession session = null; if (sessionId != null) { session = _serverData.FindSession(sessionId); if (session == null) { Log.Warn(_logMessagePrefix + "Received " + frame.Command + " frame for non-existent session: " + sessionId); var message = ErrorMessages.SessionDoesNotExistPrefix + sessionId; var errorFrame = StompFrameUtils.CreateErrorFrame(message); _transport.SendFrame(errorFrame); DisconnectWithoutLocking(); return; } if (!session.AddConnection(this)) { var message = frame.Command + " frame requested a session already in use: " + sessionId; Log.Warn(_logMessagePrefix + message); var errorFrame = StompFrameUtils.CreateErrorFrame(message); _transport.SendFrame(errorFrame); DisconnectWithoutLocking(); return; } Log.Debug(_logMessagePrefix + "Reconnected to session " + sessionId); } if (session == null) { session = _serverData.CreateSession(); session.AddConnection(this); Log.Debug(_logMessagePrefix + "Created new session " + session.SessionId); } // helps with debugging if we give the session a more friendly name session.ClientId = frame.Headers[StompHeader.NonStandard.ClientId]; _session = session; var connectedFrame = new StompFrame { Command = StompCommand.Connected, Headers = { {StompHeader.Session, session.SessionId} } }; if (frame.Headers[StompHeader.HeartBeat] == null) { // no heart-beat header received, so we default to 0,0 _negotiatedHeartBeats = new HeartBeatValues(0, 0); } else { var otherHeartBeatValues = new HeartBeatValues(frame.Headers[StompHeader.HeartBeat]); var myHeartBeatValues = new HeartBeatValues(30000, 30000); _negotiatedHeartBeats = myHeartBeatValues.CombineWith(otherHeartBeatValues); connectedFrame.Headers[StompHeader.HeartBeat] = _negotiatedHeartBeats.ToString(); } _transport.SendFrame(connectedFrame); StopConnectTimer(); StartIncomingHeartBeatTimer(); StartOutgoingHeartBeatTimer(); _stateAction = Connected; Log.Debug(_logMessagePrefix + "Session " + session + " connected"); }