Esempio n. 1
0
 protected override MessageBase CopyImpl(MessageBase clone)
 {
     // Instantiate the clone, if a derived type hasn't already.
     if (clone == null)
     {
         clone = new AcknowledgeMessage();
     }
     return(base.CopyImpl(clone));
 }
Esempio n. 2
0
		public override object ServiceMessage(IMessage message) {
			IMessage responseMessage = null;
			CommandMessage commandMessage = message as CommandMessage;
			if (commandMessage != null) {
				switch (commandMessage.operation) {
					case CommandMessage.LoginOperation:
						IPrincipal principal = null;
						try {
							principal = Authenticate(message);
						} catch (SecurityException) {
							throw;
						} catch (UnauthorizedAccessException) {
							throw;
						} catch (Exception exception) {
							string msg = __Res.GetString(__Res.Security_AuthenticationFailed);
							if (log.IsErrorEnabled)
								log.Error(msg, exception);
							throw new SecurityException(msg, exception);
						}
						if (principal == null) {
							string msg = __Res.GetString(__Res.Security_AuthenticationFailed);
							throw new SecurityException(msg);
						}
						responseMessage = new AcknowledgeMessage();
						responseMessage.body = "success";
						break;
					case CommandMessage.LogoutOperation:
						//TODO: Logs the user out of the destination. Logging out of a destination applies to everything connected using the same ChannelSet as specified in the server configuration.
						//For example, if you're connected over the my-rtmp channel and you log out using one of your RPC components, anything that was 
						//connected over the same ChannelSet is logged out.
						_messageBroker.LoginManager.Logout();
						responseMessage = new AcknowledgeMessage();
						responseMessage.body = "success";
						break;
				}
			}
			return responseMessage;
		}
Esempio n. 3
0
		private void HandleFlexClientStreamingOpenRequest(HttpRequest request, HttpResponse response, IClient flexClient) {
			Session session = FluorineContext.Current.Session as Session;
			if (session == null) {
				string msg = string.Format("Cannot grant streaming connection when ASP.NET session state is disabled", this.Id);
				if (log.IsWarnEnabled)
					log.Warn(msg);
				try {
					HandleBadRequest(msg, HttpContext.Current.Response);
				} catch (HttpException) { }
				return;
			}
			if (!_canStream || !session.CanStream) {
				string msg = string.Format("Cannot grant streaming connection, limit has been reached", this.Id);
				try {
					HandleBadRequest(msg, HttpContext.Current.Response);
				} catch (HttpException) { }
				return;
			}

			bool canStream = false;
			lock (this.SyncRoot) {
				_streamingClientsCount.Increment();
				if (_streamingClientsCount.Value == this.MaxStreamingClients) {
					canStream = true; // This thread got the last spot.
					_canStream = false;

				} else if (_streamingClientsCount.Value > this.MaxStreamingClients) {
					canStream = false; // This thread lost the last spot.
					_streamingClientsCount.Decrement();// We're not going to grant the streaming right to the client.
				} else {
					// Allow this thread to stream.
					canStream = true;
				}
			}
			if (!canStream) {
				string msg = string.Format("Cannot service streaming request, max-streaming-clients reached in endpoint {0}", this.Id);
				try {
					HandleBadRequest(msg, HttpContext.Current.Response);
				} catch (HttpException) { }
				return;
			}

			UserAgent userAgent = this.ChannelDefinition.Properties.UserAgentSettings[request.Browser.Browser];
			if (userAgent != null) {
				lock (session.SyncRoot) {
					session.MaxConnectionsPerSession = userAgent.MaxStreamingConnectionsPerSession;
				}
			}

			lock (session.SyncRoot) {
				session.StreamingConnectionsCount++;
				if (session.StreamingConnectionsCount == session.MaxConnectionsPerSession) {
					canStream = true; // This thread got the last spot in the session.
					session.CanStream = false;
				} else if (session.StreamingConnectionsCount > session.MaxConnectionsPerSession) {
					canStream = false;
					session.StreamingConnectionsCount--;
					_streamingClientsCount.Decrement();
				} else {
					canStream = true;
				}
			}
			if (!canStream) {
				string msg = string.Format("Cannot grant streaming connection, limit has been reached", this.Id);
				try {
					HandleBadRequest(msg, HttpContext.Current.Response);
				} catch (HttpException) { }
				return;
			}

			EndpointPushNotifier notifier = null;
			try {
				response.ContentType = ContentType.AMF;
				response.AppendHeader("Cache-Control", "no-cache");
				response.AppendHeader("Pragma", "no-cache");
				response.AppendHeader("Connection", "close");
				//response.AppendHeader("Transfer-Encoding", "chunked");
				response.Flush();

				// Setup for specific user agents.
				byte[] kickStartBytesToStream = null;
				int kickStartBytes = userAgent != null ? userAgent.KickstartBytes : 0;
				if (kickStartBytes > 0) {
					// The minimum number of actual bytes that need to be sent to kickstart, taking into account transfer-encoding overhead.
					try {
						int chunkLengthHeaderSize = System.Text.Encoding.ASCII.GetBytes(System.Convert.ToString(kickStartBytes, 0x10)).Length; //System.Text.ASCIIEncoding.ASCII.GetBytes(kickStartBytes.ToString("X")).Length;
						int chunkOverhead = chunkLengthHeaderSize + 4; // 4 for the 2 wrapping CRLF tokens.
						int minimumKickstartBytes = kickStartBytes - chunkOverhead;
						kickStartBytesToStream = new byte[(minimumKickstartBytes > 0) ? minimumKickstartBytes : kickStartBytes];
					} catch {
						kickStartBytesToStream = new byte[kickStartBytes];
					}
				}
				if (kickStartBytesToStream != null) {
					StreamChunk(kickStartBytesToStream, response);
				}
				try {
					notifier = new EndpointPushNotifier(this, flexClient);
					lock (_currentStreamingRequests.SyncRoot) {
						_currentStreamingRequests.Add(notifier.Id, notifier);
					}
					// Push down an acknowledgement for the 'connect' request containing the unique id for this specific stream.
					AcknowledgeMessage connectAck = new AcknowledgeMessage();
					connectAck.body = notifier.Id;
					connectAck.correlationId = OpenCommand;
					StreamMessage(connectAck, response);
				} catch (MessageException) {
				}

				if (log.IsDebugEnabled) {
					string msg = string.Format("Start streaming for endpoint with id {0} and client with id {1}", this.Id, flexClient.Id);
					log.Debug(msg);
				}

				int serverToClientHeartbeatMillis = this.ChannelDefinition.Properties.ServerToClientHeartbeatMillis >= 0 ? this.ChannelDefinition.Properties.ServerToClientHeartbeatMillis : 0;
				serverToClientHeartbeatMillis = 100;
				while (!notifier.IsClosed) {
					IList messages = notifier.GetPendingMessages();
					StreamMessages(messages, response);
					lock (notifier.SyncRoot) {
						Monitor.Wait(notifier.SyncRoot, serverToClientHeartbeatMillis);

						messages = notifier.GetPendingMessages();
						// If there are no messages to send to the client, send a 0
						// byte as a heartbeat to make sure the client is still valid.
						if ((messages == null || messages.Count == 0) && serverToClientHeartbeatMillis > 0) {
							try {
								StreamChunk(Heartbeat, response);
								response.Flush();
							} catch (HttpException) {
								break;
							} catch (IOException) {
								break;
							}
						} else {
							StreamMessages(messages, response);
						}
					}
				}
				// Terminate the response.
				StreamChunk(null, response);
				if (log.IsDebugEnabled) {
					string msg = string.Format("Releasing streaming connection for endpoint with id {0} and and client with id {1}", this.Id, flexClient.Id);
					log.Debug(msg);
				}
			} catch (IOException ex)//HttpException?
			{
				if (log.IsWarnEnabled)
					log.Warn("Streaming thread for endpoint with id " + this.Id + " is closing connection due to an IO error.", ex);
			} catch (Exception ex) {
				if (log.IsErrorEnabled)
					log.Error("Streaming thread for endpoint with id " + this.Id + " is closing connection due to an error.", ex);
			} finally {
				if (notifier != null && _currentStreamingRequests != null) {
					if (_currentStreamingRequests != null) {
						lock (_currentStreamingRequests.SyncRoot) {
							_currentStreamingRequests.Remove(notifier.Id);
						}
					}
					notifier.Close();
				}
				_streamingClientsCount.Decrement();
				lock (session.SyncRoot) {
					session.StreamingConnectionsCount--;
					session.CanStream = session.StreamingConnectionsCount < session.MaxConnectionsPerSession;
				}
			}
		}
Esempio n. 4
0
		/// <summary>
		/// Handles a message routed to the service by the MessageBroker.
		/// </summary>
		/// <param name="message">The message that should be handled by the service.</param>
		/// <returns>The result of the message processing.</returns>
		public override object ServiceMessage(IMessage message) {
			CommandMessage commandMessage = message as CommandMessage;
			MessageDestination messageDestination = GetDestination(message) as MessageDestination;
			if (commandMessage != null) {
				string clientId = commandMessage.clientId as string;
				MessageClient messageClient = messageDestination.SubscriptionManager.GetSubscriber(clientId);
				AcknowledgeMessage acknowledgeMessage = null;
				switch (commandMessage.operation) {
					case CommandMessage.SubscribeOperation:
						if (messageClient == null) {
							if (clientId == null)
								clientId = Guid.NewGuid().ToString("D");

							if (log.IsDebugEnabled)
								log.Debug(__Res.GetString(__Res.MessageServiceSubscribe, messageDestination.Id, clientId));

							string endpointId = commandMessage.GetHeader(MessageBase.EndpointHeader) as string;
							if (_messageBroker.GetEndpoint(endpointId) == null) {
								ServiceException serviceException = new ServiceException("Endpoint was not specified");
								serviceException.FaultCode = "Server.Processing.MissingEndpoint";
								throw serviceException;
							}
							commandMessage.clientId = clientId;

							if (messageDestination.ServiceAdapter != null && messageDestination.ServiceAdapter.HandlesSubscriptions) {
								try {
									acknowledgeMessage = messageDestination.ServiceAdapter.Manage(commandMessage) as AcknowledgeMessage;
								} catch (MessageException me) {
									acknowledgeMessage = me.GetErrorMessage();
									//Leave, do not subscribe
									return acknowledgeMessage;
								} catch (Exception ex) {
									//Guard against service adapter failure
									acknowledgeMessage = ErrorMessage.GetErrorMessage(commandMessage, ex);
									if (log.IsErrorEnabled)
										log.Error(__Res.GetString(__Res.ServiceAdapter_ManageFail, this.id, messageDestination.Id, commandMessage), ex);
									//Leave, do not subscribe
									return acknowledgeMessage;
								}
							}

							Subtopic subtopic = null;
							Selector selector = null;
							if (commandMessage.headers != null) {
								if (commandMessage.headers.ContainsKey(CommandMessage.SelectorHeader)) {
									selector = Selector.CreateSelector(commandMessage.headers[CommandMessage.SelectorHeader] as string);
								}
								if (commandMessage.headers.ContainsKey(AsyncMessage.SubtopicHeader)) {
									subtopic = new Subtopic(commandMessage.headers[AsyncMessage.SubtopicHeader] as string);
								}
							}
							IClient client = FluorineContext.Current.Client;
							client.Renew();
							messageClient = messageDestination.SubscriptionManager.AddSubscriber(clientId, endpointId, subtopic, selector);
							if (acknowledgeMessage == null)
								acknowledgeMessage = new AcknowledgeMessage();
							acknowledgeMessage.clientId = clientId;
						} else {
							acknowledgeMessage = new AcknowledgeMessage();
							acknowledgeMessage.clientId = clientId;
						}
						return acknowledgeMessage;
					case CommandMessage.UnsubscribeOperation:
						if (log.IsDebugEnabled)
							log.Debug(__Res.GetString(__Res.MessageServiceUnsubscribe, messageDestination.Id, clientId));

						if (messageDestination.ServiceAdapter != null && messageDestination.ServiceAdapter.HandlesSubscriptions) {
							try {
								acknowledgeMessage = messageDestination.ServiceAdapter.Manage(commandMessage) as AcknowledgeMessage;
							} catch (MessageException me) {
								acknowledgeMessage = me.GetErrorMessage();
							} catch (Exception ex) {
								//Guard against service adapter failure
								acknowledgeMessage = ErrorMessage.GetErrorMessage(commandMessage, ex);
								if (log.IsErrorEnabled)
									log.Error(__Res.GetString(__Res.ServiceAdapter_ManageFail, this.id, messageDestination.Id, commandMessage), ex);
							}
						}
						if (messageClient != null)
							messageDestination.SubscriptionManager.RemoveSubscriber(messageClient);
						if (acknowledgeMessage == null)
							acknowledgeMessage = new AcknowledgeMessage();
						return acknowledgeMessage;
					case CommandMessage.PollOperation: {
							if (messageClient == null) {
								ServiceException serviceException = new ServiceException(string.Format("MessageClient is not subscribed to {0}", commandMessage.destination));
								serviceException.FaultCode = "Server.Processing.NotSubscribed";
								throw serviceException;
							}
							IClient client = FluorineContext.Current.Client;
							client.Renew();
							try {
								acknowledgeMessage = messageDestination.ServiceAdapter.Manage(commandMessage) as AcknowledgeMessage;
							} catch (MessageException me) {
								acknowledgeMessage = me.GetErrorMessage();
							} catch (Exception ex) {
								//Guard against service adapter failure
								acknowledgeMessage = ErrorMessage.GetErrorMessage(commandMessage, ex);
								if (log.IsErrorEnabled)
									log.Error(__Res.GetString(__Res.ServiceAdapter_ManageFail, this.id, messageDestination.Id, commandMessage), ex);
							}
							if (acknowledgeMessage == null)
								acknowledgeMessage = new AcknowledgeMessage();
							return acknowledgeMessage;
						}
					case CommandMessage.ClientPingOperation:
						if (messageDestination.ServiceAdapter != null && messageDestination.ServiceAdapter.HandlesSubscriptions) {
							try {
								messageDestination.ServiceAdapter.Manage(commandMessage);
							} catch (MessageException) {
								return false;
							} catch (Exception ex) {
								//Guard against service adapter failure
								if (log.IsErrorEnabled)
									log.Error(__Res.GetString(__Res.ServiceAdapter_ManageFail, this.id, messageDestination.Id, commandMessage), ex);
								return false;
							}
						}
						return true;
					default:
						if (log.IsDebugEnabled)
							log.Debug(__Res.GetString(__Res.MessageServiceUnknown, commandMessage.operation, messageDestination.Id));
						try {
							acknowledgeMessage = messageDestination.ServiceAdapter.Manage(commandMessage) as AcknowledgeMessage;
						} catch (MessageException me) {
							acknowledgeMessage = me.GetErrorMessage();
						} catch (Exception ex) {
							//Guard against service adapter failure
							acknowledgeMessage = ErrorMessage.GetErrorMessage(commandMessage, ex);
							if (log.IsErrorEnabled)
								log.Error(__Res.GetString(__Res.ServiceAdapter_ManageFail, this.id, messageDestination.Id, commandMessage), ex);
						}
						if (acknowledgeMessage == null)
							acknowledgeMessage = new AcknowledgeMessage();
						return acknowledgeMessage;
				}
			} else {
				if (log.IsDebugEnabled)
					log.Debug(__Res.GetString(__Res.MessageServiceRoute, messageDestination.Id, message.clientId));

				if (FluorineContext.Current != null && FluorineContext.Current.Client != null)//Not set when user code initiates push
                {
					IClient client = FluorineContext.Current.Client;
					client.Renew();
				}
				object result = messageDestination.ServiceAdapter.Invoke(message);
				return result;
			}
		}
Esempio n. 5
0
		protected override MessageBase CopyImpl(MessageBase clone) {
			// Instantiate the clone, if a derived type hasn't already.
			if (clone == null)
				clone = new AcknowledgeMessage();
			return base.CopyImpl(clone);
		}
Esempio n. 6
0
		public override IMessage ServiceMessage(IMessage message) {
			if (FluorineContext.Current.Client != null)
				FluorineContext.Current.Client.Renew();

			if (message is CommandMessage) {
				CommandMessage commandMessage = message as CommandMessage;
				switch (commandMessage.operation) {
					case CommandMessage.PollOperation: {
							if (log.IsDebugEnabled)
								log.Debug(__Res.GetString(__Res.Endpoint_HandleMessage, this.Id, message.ToString()));

							if (FluorineContext.Current.Client != null)
								FluorineContext.Current.Client.Renew();

							//IMessage[] messages = null;
							IList messages = null;
							_waitingPollRequests.Increment();
							int waitIntervalMillis = this.ChannelDefinition.Properties.WaitIntervalMillis != -1 ? this.ChannelDefinition.Properties.WaitIntervalMillis : 60000;// int.MaxValue;

							if (commandMessage.HeaderExists(CommandMessage.FluorineSuppressPollWaitHeader))
								waitIntervalMillis = 0;
							//If async handling was not set long polling is not supported
							if (!FluorineConfiguration.Instance.FluorineSettings.Runtime.AsyncHandler)
								waitIntervalMillis = 0;
							if (this.ChannelDefinition.Properties.MaxWaitingPollRequests <= 0 || _waitingPollRequests.Value >= this.ChannelDefinition.Properties.MaxWaitingPollRequests)
								waitIntervalMillis = 0;

							if (message.destination != null && message.destination != string.Empty) {
								string clientId = commandMessage.clientId as string;
								MessageDestination messageDestination = this.GetMessageBroker().GetDestination(message.destination) as MessageDestination;
								MessageClient client = messageDestination.SubscriptionManager.GetSubscriber(clientId);
								client.Renew();
								//messages = client.GetPendingMessages();
							} else {
								//if (FluorineContext.Current.Client != null)
								//    messages = FluorineContext.Current.Client.GetPendingMessages(waitIntervalMillis);
							}

							if (FluorineContext.Current.Client != null) {
								IEndpointPushHandler handler = FluorineContext.Current.Client.GetEndpointPushHandler(this.Id);
								if (handler != null)
									messages = handler.GetPendingMessages();
								if (messages == null) {
									lock (handler.SyncRoot) {
										Monitor.Wait(handler.SyncRoot, waitIntervalMillis);
									}
									messages = handler.GetPendingMessages();
								}
							}

							_waitingPollRequests.Decrement();
							IMessage response = null;
							if (messages == null || messages.Count == 0)
								response = new AcknowledgeMessage();
							else {
								CommandMessage resultMessage = new CommandMessage();
								resultMessage.operation = CommandMessage.ClientSyncOperation;
								resultMessage.body = messages;
								response = resultMessage;
							}
							if (log.IsDebugEnabled)
								log.Debug(__Res.GetString(__Res.Endpoint_Response, this.Id, response.ToString()));
							return response;

						}
					case CommandMessage.SubscribeOperation: {
							/*
							if (FluorineContext.Current.Client == null)
								FluorineContext.Current.SetCurrentClient(this.GetMessageBroker().ClientRegistry.GetClient(message));
							RemotingConnection remotingConnection = null;
							foreach (IConnection connection in FluorineContext.Current.Client.Connections)
							{
								if (connection is RemotingConnection)
								{
									remotingConnection = connection as RemotingConnection;
									break;
								}
							}
							if (remotingConnection == null)
							{
								remotingConnection = new RemotingConnection(this, null, FluorineContext.Current.Client.Id, null);
								FluorineContext.Current.Client.Renew(this.ClientLeaseTime);
								remotingConnection.Initialize(FluorineContext.Current.Client);
							}
							FluorineWebContext webContext = FluorineContext.Current as FluorineWebContext;
							webContext.SetConnection(remotingConnection);
							*/

							if (this.ChannelDefinition.Properties.IsPollingEnabled) {
								//Create and forget, client will close the notifier
								IEndpointPushHandler handler = FluorineContext.Current.Client.GetEndpointPushHandler(this.Id);
								if (handler == null)
									handler = new EndpointPushNotifier(this, FluorineContext.Current.Client);
								/*
								lock (_endpointPushHandlers.SyncRoot)
								{
									_endpointPushHandlers.Add(notifier.Id, notifier);
								}
								*/
							}
						}
						break;
					case CommandMessage.DisconnectOperation: {
							if (log.IsDebugEnabled)
								log.Debug(__Res.GetString(__Res.Endpoint_HandleMessage, this.Id, message.ToString()));

							if (FluorineContext.Current.Client != null && FluorineContext.Current.Client.IsValid) {
								IList messageClients = FluorineContext.Current.Client.MessageClients;
								if (messageClients != null) {
									foreach (MessageClient messageClient in messageClients) {
										messageClient.Invalidate();
									}
								}
								FluorineContext.Current.Client.Invalidate();
							}
							if (FluorineContext.Current.Session != null) {
								FluorineContext.Current.Session.Invalidate();
							}
							//Disconnect command is received from a client channel.
							//The response returned by this method is not guaranteed to get to the client, which is free to terminate its physical connection at any point.
							IMessage response = new AcknowledgeMessage();

							if (log.IsDebugEnabled)
								log.Debug(__Res.GetString(__Res.Endpoint_Response, this.Id, response.ToString()));
							return response;
						}
				}
			}
			return base.ServiceMessage(message);
		}
Esempio n. 7
0
		/// <summary>
		/// Call this method in order to send a message from your code into the message routing system.
		/// The message is routed to a service that is defined to handle messages of this type.
		/// Once the service is identified, the destination property of the message is used to find a destination configured for that service.
		/// The adapter defined for that destination is used to handle the message.
		/// </summary>
		/// <param name="message">The message to be routed to a service.</param>
		/// <param name="endpoint">This can identify the endpoint that is sending the message but it is currently not used so you may pass in null.</param>
		/// <returns>The result of the message routing.</returns>
		internal IMessage RouteMessage(IMessage message, IEndpoint endpoint) {
			IService service = null;
			object result = null;
			IMessage responseMessage = null;

			if (log.IsDebugEnabled)
				log.Debug(__Res.GetString(__Res.MessageBroker_RoutingMessage, message.ToString()));

			CommandMessage commandMessage = message as CommandMessage;
			if (commandMessage != null && (commandMessage.operation == CommandMessage.LoginOperation || commandMessage.operation == CommandMessage.LogoutOperation))//Login, Logout
			{
				try {
					service = GetService(AuthenticationService.ServiceId);
					result = service.ServiceMessage(commandMessage);
					responseMessage = result as IMessage;
				} catch (UnauthorizedAccessException uae) {
					if (log.IsDebugEnabled)
						log.Debug(uae.Message);
					responseMessage = ErrorMessage.GetErrorMessage(message, uae);
				} catch (SecurityException exception) {
					if (log.IsDebugEnabled)
						log.Debug(exception.Message);
					responseMessage = ErrorMessage.GetErrorMessage(message, exception);
				} catch (Exception exception) {
					if (log.IsErrorEnabled)
						log.Error(__Res.GetString(__Res.MessageBroker_RoutingError), exception);
					responseMessage = ErrorMessage.GetErrorMessage(message, exception);
				}
			} else if (commandMessage != null && commandMessage.operation == CommandMessage.ClientPingOperation) {
				responseMessage = new AcknowledgeMessage();
				responseMessage.body = true;
			} else {
				//The only case when context is not set should be when one starts a new thread in the backend
				//if( FluorineContext.Current != null )
				//    FluorineContext.Current.RestorePrincipal(this.LoginCommand);
				_loginManager.RestorePrincipal();
				service = GetService(message);
				if (service != null) {
					try {
						service.CheckSecurity(message);
						result = service.ServiceMessage(message);
					} catch (UnauthorizedAccessException uae) {
						if (log.IsDebugEnabled)
							log.Debug(uae.Message);
						result = ErrorMessage.GetErrorMessage(message, uae);
					} catch (SecurityException exception) {
						if (log.IsDebugEnabled)
							log.Debug(exception.Message);
						result = ErrorMessage.GetErrorMessage(message, exception);
					} catch (ServiceException exception) {
						if (log.IsDebugEnabled)
							log.Debug(exception.Message);
						result = ErrorMessage.GetErrorMessage(message, exception);
					} catch (Exception exception) {
						if (log.IsErrorEnabled)
							log.Error(exception.Message, exception);
						result = ErrorMessage.GetErrorMessage(message, exception);
					}
				} else {
					string msg = __Res.GetString(__Res.Destination_NotFound, message.destination);
					if (log.IsErrorEnabled)
						log.Error(msg);
					result = ErrorMessage.GetErrorMessage(message, new FluorineException(msg));
				}
				if (!(result is IMessage)) {
					responseMessage = new AcknowledgeMessage();
					responseMessage.body = result;
				} else
					responseMessage = result as IMessage;
			}

			if (responseMessage is AsyncMessage) {
				((AsyncMessage)responseMessage).correlationId = message.messageId;
			}
			responseMessage.destination = message.destination;
			responseMessage.clientId = message.clientId;

			//Debug
			if (message.HeaderExists(AMFHeader.DebugHeader)) {
				log.Debug("MessageBroker processing debug header");
				ArrayList traceStack = NetDebug.GetTraceStack();
				responseMessage.SetHeader(AMFHeader.DebugHeader, traceStack.ToArray(typeof(object)) as object[]);
				NetDebug.Clear();
			}
			//The only case when we do not have context should be when the server side initiates a push
			if (FluorineContext.Current != null && FluorineContext.Current.Client != null)
				responseMessage.SetHeader(MessageBase.FlexClientIdHeader, FluorineContext.Current.Client.Id);

			if (log.IsDebugEnabled)
				log.Debug(__Res.GetString(__Res.MessageBroker_Response, responseMessage.ToString()));

			return responseMessage;
		}
Esempio n. 8
0
		public override object ServiceMessage(IMessage message) {
			CommandMessage commandMessage = message as CommandMessage;
			if (commandMessage != null) {
				//Sub/unsub handled by base class
				return base.ServiceMessage(commandMessage);
			} else {
				AsyncMessage responseMessage = null;
				DataMessage dataMessage = message as DataMessage;

				DataDestination dataDestination = this.GetDestination(dataMessage) as DataDestination;
				if (dataDestination.SubscriptionManager.GetSubscriber(dataMessage.clientId as string) == null) {
					//Subscribe here as DS doesn't send a separate subscribe command
					CommandMessage commandMessageSubscribe = new CommandMessage();
					commandMessageSubscribe.destination = dataDestination.Id;
					commandMessageSubscribe.operation = CommandMessage.SubscribeOperation;
					commandMessageSubscribe.clientId = dataMessage.clientId as string;
					string endpointId = dataMessage.GetHeader(MessageBase.EndpointHeader) as string;
					commandMessageSubscribe.headers[MessageBase.EndpointHeader] = endpointId;
					string flexClientIdHeader = dataMessage.GetHeader(MessageBase.FlexClientIdHeader) as string;
					if (flexClientIdHeader != null)
						commandMessageSubscribe.headers[MessageBase.FlexClientIdHeader] = flexClientIdHeader;
					IEndpoint endpoint = GetMessageBroker().GetEndpoint(endpointId);
					endpoint.ServiceMessage(commandMessageSubscribe);//route through the endpoint again
					//base.ServiceMessage(commandMessageSubscribe);
				}

				switch (dataMessage.operation) {
					case DataMessage.FillOperation:
						responseMessage = ExecuteFillOperation(message);
						break;
					case DataMessage.GetOperation:
						responseMessage = ExecuteGetOperation(message);
						break;
					case DataMessage.BatchedOperation:
					case DataMessage.MultiBatchOperation:
					case DataMessage.TransactedOperation:
						responseMessage = ExecuteMultiBatchOperation(message);
						break;
					case DataMessage.PageItemsOperation:
						responseMessage = ExecutePageItemsOperation(message);
						break;
					case DataMessage.PageOperation:
						responseMessage = ExecutePageOperation(message);
						break;
					case DataMessage.ReleaseCollectionOperation:
						responseMessage = ExecuteReleaseCollectionOperation(message);
						break;
					case DataMessage.GetSequenceIdOperation:
						responseMessage = ExecuteGetSequenceIdOperation(message);
						break;
					case DataMessage.ReleaseItemOperation:
						responseMessage = ExecuteReleaseItemOperation(message);
						break;
					default:
						if (log.IsErrorEnabled)
							log.Error(__Res.GetString(__Res.DataService_Unknown, dataMessage.operation));

						responseMessage = new AcknowledgeMessage();
						break;
				}
				responseMessage.clientId = message.clientId;
				responseMessage.correlationId = message.messageId;
				//Dump();
				return responseMessage;
			}
		}
Esempio n. 9
0
		private AcknowledgeMessage ExecuteMultiBatchOperation(IMessage message) {
			//May contain multiple batched, create, update or delete operations that involve 
			//more than one destination, that is, more than one remote adapter
			AcknowledgeMessage responseMessage = null;
			DataMessage dataMessage = message as DataMessage;
			IList messages = dataMessage.body as IList;

			DataServiceTransaction dataServiceTransaction = DataServiceTransaction.Begin(this);
			dataServiceTransaction.ClientId = message.clientId as string;
			//correlate al generated messages
			dataServiceTransaction.CorrelationId = message.messageId;

			string currentDestination = null;
			ArrayList currentMessageBatch = new ArrayList();

			for (int i = 0; i < messages.Count; i++) {
				DataMessage batchMessage = messages[i] as DataMessage;
				string destination = batchMessage.destination;
				DataDestination dataDestination = GetDestination(batchMessage) as DataDestination;

				if (currentDestination != null && destination != currentDestination &&
					currentMessageBatch.Count > 0) {
					MessageBatch messageBatch = ServiceBatch(message, currentMessageBatch);
					dataServiceTransaction.AddProcessedMessageBatch(messageBatch);
					currentMessageBatch = new ArrayList();
				}
				currentMessageBatch.Add(batchMessage);
				currentDestination = destination;

				if (batchMessage is UpdateCollectionMessage)
					dataServiceTransaction.AddClientUpdateCollection(batchMessage as UpdateCollectionMessage);
			}
			if (currentMessageBatch.Count > 0) {
				MessageBatch messageBatch = ServiceBatch(message, currentMessageBatch);
				dataServiceTransaction.AddProcessedMessageBatch(messageBatch);
			}

			dataServiceTransaction.Commit();
			IList outgoingMessages = dataServiceTransaction.GetOutgoingMessages();
			responseMessage = new AcknowledgeMessage();
			object[] result = new object[outgoingMessages.Count];
			outgoingMessages.CopyTo(result, 0);
			responseMessage.body = result;//outgoingMessages.ToArray(typeof(object));
			return responseMessage;
		}
Esempio n. 10
0
		private AcknowledgeMessage ExecuteReleaseItemOperation(IMessage message) {
			AcknowledgeMessage responseMessage = new AcknowledgeMessage();
			DataMessage dataMessage = message as DataMessage;
			DataDestination dataDestination = this.GetDestination(dataMessage) as DataDestination;
			dataDestination.SequenceManager.ReleaseItemOperation(dataMessage);
			return responseMessage;
		}
Esempio n. 11
0
		private AcknowledgeMessage ExecuteGetOperation(IMessage message) {
			DataMessage dataMessage = message as DataMessage;
			AcknowledgeMessage responseMessage = null;
			DataDestination dataDestination = this.GetDestination(dataMessage) as DataDestination;
			object result = dataDestination.ServiceAdapter.Invoke(message);
			if (result == null)
				responseMessage = new AcknowledgeMessage();
			else {
				ArrayList collection = new ArrayList(1);
				collection.Add(result);
				responseMessage = dataDestination.SequenceManager.ManageSequence(dataMessage, collection);
			}
			return responseMessage;
		}