Foros del Web » Creando para Internet » Flash y Actionscript »

Webservice no responde

Estas en el tema de Webservice no responde en el foro de Flash y Actionscript en Foros del Web. Hola a todos, este es mi primer post en este foro No llevo mucho tiempo trabajando con Flex, así que no controlo mucho del tema. ...
  #1 (permalink)  
Antiguo 28/04/2011, 11:14
 
Fecha de Ingreso: abril-2011
Mensajes: 2
Antigüedad: 13 años
Puntos: 0
Webservice no responde

Hola a todos, este es mi primer post en este foro

No llevo mucho tiempo trabajando con Flex, así que no controlo mucho del tema.

Mi problema es el siguiente: tengo una aplicación Flex que tiene que realizar unas llamadas a través de un webservice a una máquina que está en mi misma red. Si ejecuto la aplicación en local (no la subo a mi servidor), no tengo ningún problema para obtener respuesta del webservice, en cambio, si subo la aplicación al servidor, que está en mi propia máquina, no obtengo ninguna respuesta.

Así pues, tengo dos máquinas:

- La máquina remota tiene un servidor apache en cuya raíz está el crossdomain.xml:
Código:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy> 
<site-control permitted-cross-domain-policies="all"/> 
<allow-access-from domain="*" to-ports="*"/> 
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
A su vez tiene otro servidor para los webservices escuchando por el puerto 9000.

- Mi máquina tiene instalado otro servidor Apache, que es donde subo la aplicación.

El código de la aplicación es bastante simple:


Código:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
			    creationComplete="application1_creationCompleteHandler(event)">

	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			import mx.events.FlexEvent;
			import mx.rpc.AsyncToken;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.InvokeEvent;
			import mx.rpc.events.ResultEvent;
			import mx.rpc.soap.Operation;
			import mx.rpc.soap.SOAPFault;
			[Bindable] 
			private var employees:ArrayCollection = new ArrayCollection();
			
			protected function button1_clickHandler(event:MouseEvent):void
			{
				sgfServiceTest.CancelMission(2);
				Alert.show("Sending cancel to 2");
				
			}
			
			protected function showResult(event:ResultEvent):void
			{
				var ret:int = event.result as int;
				Alert.show("Response received = "+ ret);				
				
			}
			
			protected function application1_creationCompleteHandler(event:FlexEvent):void
			{			
				
			}
			
			protected function employeeService_resultHandler(event:ResultEvent):void
			{
				employees = event.result as ArrayCollection;
			}
			
			protected function employeeService_faultHandler(event:FaultEvent):void
			{
				Alert.show(event.fault.faultString + "\n" + event.fault.faultDetail, "Fault Information");
			}


			protected function sgfServiceTest_faultHandler(event:FaultEvent):void
			{
				Alert.show(event.fault.faultString + "\n" + event.fault.faultDetail, "Fault Information");
			}


			protected function sgfServiceTest_invokeHandler(event:InvokeEvent):void
			{
				
				Alert.show(event.message.toString(), "Invoke Information");
			}

		]]>
	</fx:Script>

	<fx:Declarations>
		<mx:WebService				
			id="sgfServiceTest"
			wsdl="http://192.168.1.235/SGF.wsdl"			
			port="SGF"			
			fault="mx.controls.Alert.show(event.fault.faultString)"
			result="showResult(event)"
			invoke="sgfServiceTest_invokeHandler(event)">		
		</mx:WebService>
		
		
	</fx:Declarations>
	<s:Button x="298" y="161" label="Cancel" click="button1_clickHandler(event)"/>
</s:Application>
- El xml que obtengo del servidor es éste:


Código:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="SGF"
 targetNamespace="http://192.168.1.235/SGF.wsdl"
 xmlns:tns="http://192.168.1.235/SGF.wsdl"
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 
 xmlns:ns="urn:SGF"
 xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
 
 xmlns:MIME="http://schemas.xmlsoap.org/wsdl/mime/"
 
 xmlns:DIME="http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/"
 
 xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
 
 xmlns="http://schemas.xmlsoap.org/wsdl/">



<types>

 <schema targetNamespace="urn:SGF"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:ns="urn:SGF"
  xmlns="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">
  <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"/>
  <import namespace="http://xml.apache.org/xml-soap"/>


 </schema>

</types>

<message name="CancelMissionRequest">
 <part name="iRobot" type="xsd:int"/>
</message>

<message name="CancelMissionResponse">
 <part name="iResult" type="xsd:int"/>
</message>

<portType name="SGFPortType">
 <operation name="CancelMission">
  <documentation>Service definition of function ns__CancelMission</documentation>
  <input message="tns:CancelMissionRequest"/>
  <output message="tns:CancelMissionResponse"/>
 </operation>
</portType>

<binding name="SGF" type="tns:SGFPortType">
 <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
 <operation name="CancelMission">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:SGF" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:SGF" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
</binding>

<service name="SGF">
 <documentation>Sistema gestion</documentation>
 <port name="SGF" binding="tns:SGF">
  <SOAP:address location="http://192.168.1.235:9000"/>
 </port>
</service>

</definitions>
He estado buscando bastante y aún no he encontrado dónde está el fallo. No sé si es cosa de la configuración del servidor, del crossdomain, de que el servidor está escuchando por un puerto distinto al 80 y eso no le gusta...

En fin, cualquier aportación será bien recibida :)

Gracias de antemano.
  #2 (permalink)  
Antiguo 04/05/2011, 06:19
 
Fecha de Ingreso: abril-2011
Mensajes: 2
Antigüedad: 13 años
Puntos: 0
Respuesta: Webservice no responde

Bueno, he seguido mirando y creo que he encontrado el problema y un par de posibles soluciones. Se ve que a partir de la versión 9.0xx de flash, las restricciones de seguridad cambiaron y ya no es suficiente con el crossdomain.xml:

Cita:
you do not have the same security restrictions when testing your application from the flex builder compared to starting your swf through the flash player (since flash player 9.0xxx the security settings have been changed quite a bit - that´s why the settings in the crossdomain.xml in the domain you´re using is not sufficient)
you´d have to use some kind of proxy to 'pass' the data to your application - do this (the 'quick and diry' approach - you´d have to change the values for the service you are using)
Así que para poder llamar al webservice, necesita hacerse a través de un proxy para evitar las restricciones de seguridad.

Para realizar esto, podemos hacerlo de al menos dos maneras:
  • Por medio del servidor [URL="http://opensource.adobe.com/wiki/display/blazeds/BlazeDS"]BlazeDs[/URL], que hará de proxy. Esta solución aún no la he probado.
  • Implementando una clase en php que haga la llamada al webservice. Para implementar esta clase me he valido de la librería de componentes [URL="http://framework.zend.com/manual/en/learning.quickstart.intro.html"]ZendFramework[/URL], que ya había utilizado con Flex anteriormente.

Para las pruebas iniciales he creado la siguiente clase en un fichero .php:

Código:
class WebserviceProxy {

	var $connection;
	

	public function __construct() {
		set_include_path('../ZendFramework/library/');
		require_once('Zend/Soap/Client.php');		
		$this->connection = new Zend_Soap_Client('http://192.168.1.235/doc.wsdl');		
	}

	public function cancelMission($mission_id) {
		$response = $this->connection->CancelMission($mission_id);
		
		return $response;
	}

}
Una vez tenemos la clase, la podemos importar desde Flash Builder > "Connect to Data/Service" > "PHP" > "Browse PHP Class" y seleccionamos la clase que acabamos de crear, con lo que solamente tendremos que declarar un objeto de ese servicio y realizar la llamada. Finalmente el código quedaría algo parecido a esto:

Código:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
			    creationComplete="application1_creationCompleteHandler(event)">

	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			import mx.events.FlexEvent;
			import mx.rpc.AsyncToken;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.InvokeEvent;
			import mx.rpc.events.ResultEvent;
			import mx.rpc.soap.Operation;
			import mx.rpc.soap.SOAPFault;
			
			import services.webserviceproxy.WebserviceProxy;
			[Bindable] 
			private var employees:ArrayCollection = new ArrayCollection();
			private var webserviceProxy:WebserviceProxy = new WebserviceProxy();
			
			protected function button1_clickHandler(event:MouseEvent):void
			{
				
				cancelMissionResult.token = webserviceProxy.cancelMission(5);
				Alert.show("Sending cancel to 5");
				
			}
			
			protected function resultCancelHandler(event:ResultEvent):void
			{
				Alert.show("Result cancel = " + event.result.toString());
			}


			protected function cancelMissionResult_resultHandler(event:ResultEvent):void
			{
				var ret:int = event.result as int;
				Alert.show("Response received = "+ ret);	
			}


			protected function cancelMissionResult_faultHandler(event:FaultEvent):void
			{
				Alert.show(event.fault.faultString + "\n" + event.fault.faultDetail, "Fault Information");
			}

		]]>
	</fx:Script>

	<fx:Declarations>
		
		<s:CallResponder id="cancelMissionResult" result="cancelMissionResult_resultHandler(event)"
						  fault="cancelMissionResult_faultHandler(event)" />
		
	</fx:Declarations>
	<s:Button x="298" y="161" label="Cancel" click="button1_clickHandler(event)"/>
</s:Application>
Bueno, espero que esta solución le sirva a alguien

Etiquetas: flex, responde, webservice
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 06:51.