Пример #1
0
		private IDictionary Invoke(IDictionary request) {
			ValidationUtils.ArgumentNotNull(request, "request");
			object error = null;
			object result = null;

			ISession session = this.MessageBroker.SessionManager.GetHttpSession(HttpContext.Current);
			FluorineContext.Current.SetSession(session);
			//Context initialized, notify listeners.
			if (session != null && session.IsNew)
				session.NotifyCreated();

			// Get the ID of the request.
			object id = request["id"];
			string credentials = request["credentials"] as string;
			if (!StringUtils.IsNullOrEmpty(credentials)) {
				try {
					CommandMessage commandMessage = new CommandMessage(CommandMessage.LoginOperation);
					commandMessage.body = credentials;
					IMessage message = this.MessageBroker.RouteMessage(commandMessage);
					if (message is ErrorMessage) {
						error = FromException(message as ErrorMessage);
						return CreateResponse(id, result, error);
					}
				} catch (Exception ex) {
					error = FromException(ex);
					return CreateResponse(id, result, error);
				}
			}

			// If the ID is not there or was not set then this is a notification
			// request from the client that does not expect any response. Right
			// now, we don't support this.
			bool isNotification = JavaScriptConvert.IsNull(id);

			if (isNotification)
				throw new NotSupportedException("Notification are not yet supported.");

			log.Debug(string.Format("Received request with the ID {0}.", id.ToString()));

			// Get the method name and arguments.
			string methodName = StringUtils.MaskNullString((string)request["method"]);

			if (methodName.Length == 0)
				throw new JsonRpcException("No method name supplied for this request.");

			if (methodName == "clearCredentials") {
				try {
					CommandMessage commandMessage = new CommandMessage(CommandMessage.LogoutOperation);
					IMessage message = this.MessageBroker.RouteMessage(commandMessage);
					if (message is ErrorMessage) {
						error = FromException(message as ErrorMessage);
						return CreateResponse(id, result, error);
					} else
						return CreateResponse(id, message.body, null);
				} catch (Exception ex) {
					error = FromException(ex);
					return CreateResponse(id, result, error);
				}
			}

			//Info("Invoking method {1} on service {0}.", ServiceName, methodName);

			// Invoke the method on the service and handle errors.
			try {
				RemotingMessage message = new RemotingMessage();
				message.destination = this.Request.QueryString["destination"] as string;
				message.source = this.Request.QueryString["source"] as string;
				message.operation = methodName;
				object argsObject = request["params"];
				object[] args = (argsObject as JavaScriptArray).ToArray();
				message.body = args;
				IMessage response = this.MessageBroker.RouteMessage(message);
				if (response is ErrorMessage)
					error = FromException(response as ErrorMessage);
				else
					result = response.body;

				/*
				Method method = serviceClass.GetMethodByName(methodName);

				object[] args;
				string[] names = null;

				object argsObject = request["params"];
				IDictionary argByName = argsObject as IDictionary;

				if (argByName != null)
				{
					names = new string[argByName.Count];
					argByName.Keys.CopyTo(names, 0);
					args = new object[argByName.Count];
					argByName.Values.CopyTo(args, 0);
				}
				else
				{
					args = (argsObject as JavaScriptArray).ToArray();
				}

				result = method.Invoke(instance, names, args);
				 */
			} catch (Exception ex) {
				log.Error(ex.Message, ex);
				throw;
			}

			// Setup and return the response object.
			return CreateResponse(id, result, error);
		}
Пример #2
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);
		}
Пример #3
0
		/// <summary>
		/// Accept a command from the adapter's service (subscribe, unsubscribe and ping operations).
		/// </summary>
		/// <param name="commandMessage"></param>
		/// <returns></returns>
		public virtual object Manage(CommandMessage commandMessage) {
			return new AcknowledgeMessage();
		}
Пример #4
0
		/// <summary>
		/// Invalidates the MessageClient.
		/// </summary>
		/// <param name="notifyClient">Push a subscription invalidation message to the client.</param>
		public void Invalidate(bool notifyClient) {
			lock (this.SyncRoot) {
				if (!IsValid || IsInvalidating)
					return; // Already shutting down.

				SetIsInvalidating(true);
				_messageDestination.SubscriptionManager.CancelTimeout(this);
			}

			// Build a subscription invalidation message and push to the client if it is still valid.
			if (notifyClient && _client != null && _client.IsValid) {
				CommandMessage commandMessage = new CommandMessage();
				commandMessage.destination = _messageDestination.Id;
				commandMessage.clientId = _clientId;
				commandMessage.operation = CommandMessage.SessionInvalidateOperation;

				MessageService messageService = _messageDestination.Service as MessageService;
				object[] subscribers = new object[] { commandMessage.clientId };
				try {
					messageService.PushMessageToClients(subscribers, commandMessage);
				} catch (MessageException) { }
			}

			// Notify listeners that we're being invalidated.
			if (_messageClientDestroyedListeners != null && _messageClientDestroyedListeners.Count != 0) {
				foreach (IMessageClientListener listener in _messageClientDestroyedListeners.Keys) {
					listener.MessageClientDestroyed(this);
				}
				_messageClientDestroyedListeners.Clear();
			}

			// Generate unsubscribe messages for all of the MessageClient's subscriptions and 
			// route them to the destination this MessageClient is subscribed to.
			// Some adapters manage their own subscription state.
			ArrayList unsubscribeMessages = new ArrayList();
			lock (this.SyncRoot) {
				foreach (SubscriptionInfo subscription in _subscriptions) {
					CommandMessage unsubscribeMessage = new CommandMessage();
					unsubscribeMessage.destination = _messageDestination.Id;
					unsubscribeMessage.clientId = _clientId;
					unsubscribeMessage.operation = CommandMessage.UnsubscribeOperation;
					unsubscribeMessage.SetHeader(CommandMessage.SessionInvalidatedHeader, true);
					unsubscribeMessage.SetHeader(CommandMessage.SelectorHeader, subscription.Selector);
					unsubscribeMessage.SetHeader(AsyncMessage.SubtopicHeader, subscription.Subtopic);
					unsubscribeMessages.Add(unsubscribeMessage);
				}
			}
			// Release the lock and send the unsub messages.
			foreach (CommandMessage commandMessage in unsubscribeMessages) {
				try {
					_messageDestination.Service.ServiceMessage(commandMessage);
				} catch (MessageException me) {
					if (log.IsDebugEnabled)
						log.Debug("MessageClient: " + _clientId + " issued an unsubscribe message during invalidation that was not processed but will continue with invalidation.", me);
				}
			}

			//TODO
			RemoveSubscription(this.Selector, this.Subtopic);

			lock (this.SyncRoot) {
				// If we didn't clean up all subscriptions log an error and continue with shutdown.
				int remainingSubscriptionCount = _subscriptions.Count;
				if (remainingSubscriptionCount > 0 && log.IsErrorEnabled)
					log.Error("MessageClient: " + _clientId + " failed to remove " + remainingSubscriptionCount + " subscription(s) during invalidation");
			}

			_messageDestination.SubscriptionManager.RemoveSubscriber(this);

			lock (this.SyncRoot) {
				SetIsValid(false);
				SetIsInvalidating(false);
			}
		}
Пример #5
0
		protected override MessageBase CopyImpl(MessageBase clone) {
			// Instantiate the clone, if a derived type hasn't already.
			if (clone == null)
				clone = new CommandMessage();
			// Allow base type(s) to copy their state into the new clone.
			base.CopyImpl(clone);
			// Copy our state into the clone.
			((CommandMessage)clone)._messageRefType = _messageRefType;
			((CommandMessage)clone)._operation = _operation;
			return clone;
		}
Пример #6
0
		public override object Manage(CommandMessage commandMessage) {
			object result = base.Manage(commandMessage);
			switch (commandMessage.operation) {
				case CommandMessage.SubscribeOperation:
					lock (SyncRoot) {
						bool enableReceive = _consumers.Count == 0;
						_consumers[commandMessage.clientId] = null;
						if (enableReceive)
							EnableReceiving(true);
					}
					break;
				case CommandMessage.UnsubscribeOperation:
					lock (SyncRoot) {
						if (_consumers.Contains(commandMessage.clientId)) {
							_consumers.Remove(commandMessage.clientId);
							if (_consumers.Count == 0)
								EnableReceiving(false);
						}
					}
					break;
			}
			return result;
		}
Пример #7
0
		/// <summary>
		/// Closes the handler.
		/// </summary>
		public void Close() {
			lock (this.SyncRoot) {
				if (IsClosed || IsClosing)
					return;
				SetIsClosing(true);
			}
			if (_session != null)
				_session.RemoveSessionDestroyedListener(this);
			_flexClient.UnregisterEndpointPushHandler(this, _endpoint.Id);

#if !(NET_1_1)
			List<IMessage> list = new List<IMessage>(1);
#else
            ArrayList list = new ArrayList(1);
#endif
			CommandMessage disconnect = new CommandMessage(CommandMessage.DisconnectOperation);
			PushMessage(disconnect);

			// Invalidate associated subscriptions. This doesn't attempt to notify the client.
			foreach (MessageClient messageClient in _messageClients)
				messageClient.Invalidate();

			lock (this.SyncRoot) {
				SetIsClosed(true);
				SetIsClosing(false);
			}
			lock (this.SyncRoot) {
				Monitor.PulseAll(this.SyncRoot);
			}
		}
Пример #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;
			}
		}