Comunidad de diseño web y desarrollo en internet online

Problema al enviar datos de un servidor de sockets a flash

Citar            
MensajeEscrito el 01 Ago 2011 10:38 am
Hola amigos de cristalab
Tengo un problema que no se como solucionarlo.

Estoy haciendo un juego multijugador en tiempo real de aviones usando un servidor de sockets php.

El problema viene cuando el servidor envía a un solo cliente flash varios mensajes consecutivos, el cliente solo recibe el primero y el resto se pierden.

Si por ejemplo aplico un retardo en el envió de cada mensaje flash recibe correctamente todos los mensajes pero no es una solución porque la técnica que quiero utilizar para mover a los jugadores es enviando las teclas pulsada (keystrokes) y si aplico un retardo entre cada tecla pulsada entonces no se refleja correctamente los jugadores en la posición correcta.

Ejemplo simple 1

Servidor

Código PHP :

 

/*Supongamos que 4 clientes saludan a la vez en un chat y le enviamos el saludo al mismo cliente*/

socket_write($client, "hello1".chr(0x00));
socket_write($client, "hello2".chr(0x00));
socket_write($client, "hello3".chr(0x00));               
socket_write($client, "hello4".chr(0x00));




Cliente flash

Código ActionScript :


function onEnterDataSocket(event:ProgressEvent):void {
var buffer:String = socket.readUTFBytes(socket.bytesAvailable);
trace(buffer);
//El resultado del trace es únicamente “hello1”
}





Ejemplo sencillo 2. Así funciona correctamente pero no es una opción para enviar keystrokes

Servidor

Código PHP :


/*Esta vez enviamos los 4 mensajes pero con un tiempo de espera de 1 segundo entre cada uno*/

socket_write($client, "hello1".chr(0x00));
Sleep(1);
socket_write($client, "hello2".chr(0x00));
Sleep(1);
socket_write($client, "hello3".chr(0x00));               
Sleep(1);
socket_write($client, "hello4".chr(0x00));




Cliente flash

Código ActionScript :


function onEnterDataSocket(event:ProgressEvent):void {
var buffer:String = socket.readUTFBytes(socket.bytesAvailable);
trace(buffer);
/*El resultado seria
                  hello1 
                  hello2
                  hello3
                  hello4*/
}



Si alguien se ha encontrado en la misma situación y ha conseguido solucionarlo o alguien sabe alguna otra técnica para poder solventar el problema agradecería que me diera alguna solución
De ante mano muchas gracias
Saludos

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 01 Ago 2011 01:26 pm
Es interesante lo que planteas, recuerdo haber fracasado cuando escribí el socket en PHP porque a los servidores shared no les gusta tener demonios por allí y los matan (mi servidor de socket moría a los pocos segundos) No tengo claro porqué le agregas el primer byte al string:

"hello1".chr(0x00)

De todas formas si miras el primer comentario de todos de socket_write verás que dice esto>

Some clients (Flash's XMLSocket for example) won't fire a read event until a new line is recieved.

Y sugiere agregar el newline a cada mensaje

$msg = "$msg\n\0";

Miralo en http://php.net/manual/en/function.socket-write.php, primer comentario

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 02 Ago 2011 07:31 am
Hola de nuevo solisarg, ya sé que los servidores no permiten los demonios pero siempre se puede acudir a un servidor dedicado aunque son muy caros, en mi caso he montado un servidor en casa con un ordenador dedicado solo para eso y la idea es optimizar al máximo los datos que se envían al servidor para ocupar el menos ancho de banda posible. Lo primero que hice fue programar un chat a modo de experimentación que lo tengo en el foro montado y a raíz de hay empecé a programar el juego.
Sobre lo de poner el primer byte al string lo ley en foros en ingles que también sugerían terminar los mensajes con eso, ahora he probado con terminar los mensajes con newline y cero, aunque haciendo eso ahora desde el cliente tengo que encargarme de eliminar el carácter de nueva línea cuando entra el mensaje y es un comando, de todas maneras obtengo el mismo resultado cuando el server envía múltiples mensajes al mismo tiempo a un mismo cliente este no los recibe todos.
Esto es lo que el server envía a todos los clientes cada vez que uno de ellos pulsa una tecla

Código PHP :

foreach($cli as $client) {
// socket_write("clientToSend = 1","/comando = sendStrokes % idDelClienteKApulsadoUnaTecla = 2 % keyCode = 30% pulsadaOsoltada =  1/0 % \n\0");
socket_write($client[0],"/sendStrokes%".intval($socket)."%".$keystrokes. "%\n\0");
}

El cliente flash cuando recibe ese mensaje comprueba el primer character si es un “/” sabe que es un comando de entrada del juego y no un mensaje normal del chat , separo los parámetros con split(%) y mediante IF’s compruebo el comando y recupero el id del cliente que ha pulsado la tecla, busco el objeto con ese id dentro de un array y le paso los keystrokes para que actualice su posición.
Esta técnica funciona correctamente hasta que falla algún mensaje por ejemplo si estoy desplazándome hacia arriba UP envio a todos los clientes la tecla pulsada junto a un 1
ej. (30%1) si suelto la tecla envio la tecla pulsada junto con un 0 ej. (30%0) a todos los clientes pero si pulso y suelto la tecla muy rápido el mensaje conforme he soltado la tecla no llega y el objeto o jugador que me representa en las demás pantallas de los clientes se queda moviéndose indefinidamente porque no ha recibido la orden de que la tecla ha sido soltada (30%0).
E probado de enviar en vez de las teclas pulsadas de una en una un array con el estado de todas las teclas cada vez que se pulsa una tecla o se suelta y más o menos compensa el que algún cliente flash no reciba algún mensaje pero aun así sigue fallando si pulso cierta combinación de teclas y las suelto muy rápido.
Definitivamente flash no es capaz de recepcionar/procesar los mensajes con la misma velocidad que es capaz de emitirlos el servidor, deberían implementar a la clase socket de flash una especie de buffer de cola, donde se pudieran almacenar los mensajes múltiples que llegasen y disparar el evento a medida que se fueran descargando o algo por el estilo.
He probado también de intercalar usleep() entre mensaje y mensaje para dormir el script del servidor unas milésimas de segundo pero aun así hay veces que flash no recibe los mensajes y si aumento el retardo funciona bien pero los movimientos nos son en tiempo real y las posiciones se descuadran.
En fin solisarg si se te ocurre alguna solución te agradecería que me iluminaras Xd
Saludos

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 02 Ago 2011 08:51 am
Bueno acabo de descubrir que el servidor cuando recive multiples mensajes muy seguidos los junta en uno solo, por esa razon perdia pulsaciones de teclado por el camino
Si soluciono el problema lo comento.

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 02 Ago 2011 10:55 am
Nada el servidor juntava los mensajes porque dormia el script con usleep, vuelvo a estar al principio.

E pensado que la solucion podria ser que si el servidor va a enviar varios mensajes consecutivos al cliente flash en menos de medio segundo pues que concatene los mensajes y enviarlos en un solo mensaje y si son mensajes con un intervalo superios a medio segundo que los envie sueltos, pero no se me ocurre como crear un script del lado del servidor que controle esto.

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 02 Ago 2011 01:38 pm
Los juegos de acción son muy complicados para trabajar en red. Imagina que estás tirando contra una máquina en tu propia red, si lo llevas a un servidor real verás como disparos atraviesan paredes y personajes siguen corriendo al infinito. Depende del tipo de juego se puede hacer programación deductiva para atenuar esto, es decir la tecla setea velocidad, no hace que el personaje se mueva 5 px por decir. Al soltarla la velocidad pasa a 0. Todo tiene que estar apuntado a minimizar la cantidad de mensajes, e incluso se suele introducir un pequeño delay en el refresco del resto de los clientes para compensar perdidas (antes de que la bala llegue, ya se que le ha dado y esta muerto)
Si te consuela, no es un tema de tu sistema de sockets en PHP, mas o menos todos los sistemas incluído FMS con el socket basado en RemoteSharedObject sufren de lo mismo. Hay un límite de latencia a partir del cual jugar se hace imposible, y luego grados que tienen que ver con la anticipación del movimiento y el tipo de juego.
En síntesis, no hay una solución definitiva sino paliativos y definitivamente juegos de acción que son inviables (quien no ha visto caer a alguien sin siquiera ver la bala jugando en red) Llegarás a un cierto grado de realismo, pero definitivamente la latencia promedio tiene que ser un punto de partida para tu juego multiusuario, pues forma parte de la misma estructura de la red

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 02 Ago 2011 06:10 pm
gracias Solisarg, prácticamente ya me he encontrado con todos los puntos que comentas y más o menos lo he solucionado, pero con flash además de todo eso se suma que no es capaz de recepcionar múltiples mensajes a la vez, en cambio con un cliente hecho en c++ o vb si son capaces.

Me las he tenido que arreglar para medir el número de pulsaciones en x tiempo, si durante ese tiempo se han pulsado y soltado 3 o 4 teclas de golpe solo contara la última acción

Código ActionScript :

import flash.events.TimerEvent;
import flash.utils.Timer;
var concatArr:Array = new Array();
var t:Timer = new Timer(80,1);
function sendKeys(keystrokes:Array):void {
if (t.running) {
   concatArr.push("/sendKeys"+HERO.id+"%"+keystrokes);
} else {
   concatArr.push("/sendKeys"+HERO.id+"%"+keystrokes);
   t.addEventListener(TimerEvent.TIMER, sendStrokes);
   t.start();
}
}
function sendStrokes(e:TimerEvent):void {
t.removeEventListener(TimerEvent.TIMER, sendStrokes);
flush(concatArr[concatArr.length-1]);
concatArr = [];
}
function flush(buffer:*):void {
socket.writeUTFBytes(buffer);
socket.flush();
}

asi consigo enviar una acción cada x tiempo y el servidor luego no satura el cliente

El problema es que si aumento el retardo de salida de los mensajes los movimientos
tardan en responder y no son tan suaves si disminuyo el retardo, el movimiento es mas rapido y suave pero me arriesgo a que la nave en un apretujón repetido de teclas acabe volando al infinito y al mas allá sin parar.

Bueno como soy muy cabezón voy a seguir intentando crear un juego en tiempo real y si fracaso pues nada esa experiencia que me llevo.

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 26 Mar 2012 12:27 pm
Llevo un dia entero con este mismo problema. Y no entendía porqué pasaba. Que decepcion, resulta que actionscript no está optimizado para recibir varios mensajes al mismo tiempo :(

Al principio pensaba que era el servidor php, pero nó. Es AS3.

En cuanto a la solucion que he tomado: Cada vez que el servidor envia un mensaje a un usuario, guardo el microtime de cuando se envió. Y en el siguiente mensaje que se le envie al mismo usuario compruebo si hay 10 milisegundos de diferencia entre uno y otro. Si no hay 10 milisegundos de diferencia. Entonces duermo el script 10 milisegundos usleep(10000);

En realidad esta solucion no vale de mucho, porque si retrasas el server en cada mensaje a la larga cuando tengas muchos usuarios, estos van a tener mas latencia (aunque 10 milisegundos no es mucho) que la que deberian tener. Es decir, con as3 no se pueden hacer juegos multiplayer a tiempo real. Afortunadamente el juego que estoy haciendo es un juego de estrategia por turnos. Pero me jode saber que en un futuro no podre hacer juegos de accion con latencia baja.

En fin. Esperemos que adobe algun día solucione este problema.

Saludos a todos. Y gracias por el post me ha servido para saber que no era problema de mi codigo (mal de muchos consuelo de tontos :P).

Por EnZo

7 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Mar 2012 01:47 pm
Al mismo tiempo supongo que no, ¿hiciste prueba de intervalos cortos? ¿El límite que encontraste es 10 ms?

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 26 Mar 2012 02:28 pm

solisarg escribió:

Al mismo tiempo supongo que no, ¿hiciste prueba de intervalos cortos? ¿El límite que encontraste es 10 ms?

Jorge


He probado a dormirlo 1 milisegundo y me fallaba. No he probado el rango de 1 a 10.

Por EnZo

7 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Mar 2012 05:20 pm
Igual es altamente probable que sean 100% concurrentes. Un juego con mucha carga de gente puede tener mensajes en ese rango, pero 10 ms debería estar bien.

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 26 Mar 2012 05:24 pm
Que fuerte. Me está pasando lo mismo pero a la inversa. Si envio muchos mensajes al servidor desde un cliente/usuario en ocasiones se solapa y envia los dos a la vez de seguido.

Ahora no se interpretar si es problema de php o de flash.

Por EnZo

7 de clabLevel



 

firefox
Citar            
MensajeEscrito el 26 Mar 2012 08:03 pm
Otro tema a tener en cuenta. Antes he comentado
"Y en el siguiente mensaje que se le envie al mismo usuario compruebo si hay 10 milisegundos de diferencia entre uno y otro"

No basta con que la diferencia sean 10 milisegundos. Si la diferencia es de 130 milisegundos tambien se solapan los mensajes. Así que he tenido que cambiar el comparador de 10 a 200 milisegundos. Pero ojo, lo importante es que se puede seguir durmiendo 10 milisegundos nada más.

Código PHP :

if ((Timer::microtime()-$lastSent)<200)
  usleep(10000);

Por EnZo

7 de clabLevel



 

firefox
Citar            
MensajeEscrito el 27 Mar 2012 08:07 am
Saludos, ya no me acordaba de que abrí este tema y que además al final lo solucione, como ayer me llego un aviso al móvil de que había nuevas respuestas para el tema pues me acercado para explicar la solución.
El problema era que yo daba por hecho que el listener de escucha de la entrada de los datos se debía ejecutar cada vez que entraban datos, al fin y al cabo realmente hace eso pero con un detalle y es que si desde el servidor al cliente flash se envían varios datos consecutivos estos se concatenan, es decir el listener se ejecuta y devuelve los datos acumulados o sea los datos no se pierden como yo pensaba, lo que ocurre es que se mantiene un flujo de datos constantes cuando existen multiples envíos consecutivos desde el servidor al cliente, por lo tanto la solución es sencilla tenemos que encargarnos de separar los datos nosotros, por ejemplo imaginemos que enviamos la cadena “hola” desde el servidor al cliente, el listener del cliente que permanece a la escucha se ejecutara y nos devolverá la cadena “hola”, ahora imaginemos que el servidor envía al cliente varias cadenas por separado consecutivas con una diferencia solo de varias milésimas por ejemplo las cadenas “hola” y “que tal” cuando lleguen al cliente dichas cadenas el listener que está a la escucha no se ejecutara dos veces como pensamos que debería ocurrir es decir el listener debería ejecutarse una vez por la cadena “hola” y otra por la cadena “que tal” pero no es así, lo que ocurre es que al recibir los datos tan consecutivos el listener solo se ejecuta una vez devolviendo las dos cadenas juntas “hola que tal” por lo tanto lo que debemos hacer es enviar desde el servidor las cadenas y los comandos precedidos por un símbolo para después separarlos y ejecutarlos mediante un for.
La verdad es que la solución es sencilla aunque me di cuenta por suerte mientras trasteaba con el juego que estaba haciendo, así mis perdones a adobe por echarle las culpas xD
Para los que quieran ver que si se puede hacer un juego completamente en tiempo real con flash aquí les dejo un enlace a un video que hice.

http://blog.xavirobot.com/etapa-2-probando-las-armas-del-juego-rog-battle-arena-multiplayer-flash-version/

El servidor lo hice con php y luego lo rehíce de nuevo en adobe air porque php no soporta multihilo y me estaba encontrando con muchos problemas. Si tengo tiempo mirare de poner el trozo de código encargado de gestionar los datos de entrada del cliente.

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 27 Mar 2012 01:37 pm
El servidor lo hice con php y luego lo rehíce de nuevo en adobe air


No entiendo, PHP es del lado del servidor y supongo con eso gestionabas el servidor de sockets, pero AIR es para el cliente ... ¿como lo reemplazaste?

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 28 Mar 2012 06:13 am
Hola solis, es hasta mas sencillo implementar el servidor de sockets en adobe air que en php, el servidor en adobe air lo hice para ejecutarlo en un servidor propio de casa, aunque si dispones de un servidor dedicado de pago tambien puedes intalar el servidor de sockets de Air.

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 28 Mar 2012 07:12 am
Se me olvido, si tambien se os concatenan las cadenas del cliente al servidor la solucion es la misma enviar cada cadena precedida de un simbolo y cuando lleguen al servidor separarlas y ejcutarlas con un for

Aqui dejo un ejemplo del lado del cliente


Imaginemos que el servidor envía tres cadenas al cliente por separado pero en un corto plazo de tiempo.

/loadmap%Ardenas
/serverStatus%LOADING
/chat%23%hola este es un texto para el chat y mi id es el 23

El listener no se ejecutara por cada cadena si no que se ejecutara una sola vez devolviendo las 3 cadenas juntas, por lo tanto el buffer de la función onEnterDataSocket recibirá las cadenas de la siguiente manera

/loadmap%Ardenas/serverStatus%LOADING/chat%23%hola este es un texto para el chat y mi id es el 23

De estas cadenas solo hay que entender que el texto después del símbolo / es el comando que debe ejecutarse y que los textos separados con el símbolo % son los parámetros, en definitiva le estamos diciendo al cliente que ejecute el comando loadMap y que cargue el mapa Ardenas, que ponga el estado del servidor en LOADING y muestre un texto de chat.

Código ActionScript :

function onEnterDataSocket(buffer:String):void {//Se ejecuta cada vez que entran datos

    var allCommands:Array = new Array();
   
//Separamos la cadena recibida en un array especificando el símbolo / como separador

    allCommands = buffer.split("/");
   
//Eliminamos el primer elemento puesto que es un elemento que siempre estará vacio a consecuencia de la inexistencia de texto //que anteceda al primer símbolo / a la hora de separarlos.

    allCommands.shift();
    var count:int = allCommands.length; //El resultado serán 3 elementos / comandos
 
 
 //Ahora recorremos cada elemento del array de comandos
    for (var mt:int = 0; mt<count; mt++) {
 
        var arr:Array = new Array();

//Separamos el comando de sus parámetros en un nuevo array sabiendo que el nombre del comando siempre estará en la posición 0 del nuevo array arr

        arr = allCommands[mt].split("%");  
 
        // (1)EL SERVIDOR MANDA CARGAR MAPA 
        if (arr[0] == "loadMap") { // Si el comando recibido es loadMap entonces
            GAME_STATUS = "LOADINGMAP"
            loadMap(arr[1]);//cargamos el mapa ardenas
        }
      //EL SERVIDOR ENVIA EL ESTADO
        if (arr[0] == "serverStatus") { // Si el comando es  serverStatus  entonces
            GAME_STATUS = arr[1];
        }
  //SE RECIVEN LOS MENSAJE DE CHAT
         if (arr[0] == "chat") { // Si el comando es chat entonces
            chat.input(userid = arr[1], textUser = arr[2]);
        }
}
}


A medida que se vayan añadiendo más comandos se pueden ir añadiendo mas ifs else if con esta técnica ya no importa que se solapen las cadenas y evitamos los retrasos ya solo dependeremos de la velocidad del envió de las cadenas y el procesamiento de cada máquina y de la optimización en el envió de los comandos cuanto más cortos mejor.

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 28 Mar 2012 07:35 am
Hola de nuevo a todos. Has hecho tests enviando varios mensajes desde el servidor AIR al cliente, para ver si se solapan? Si es así salimos de dudas y sabemos que es problema de Flash Player.

En cuanto a tu solucion, la habia pensado. Pero mi problema es que yo encripto y comprimo los mensajes, entonces no puedo usar un caracter/byte especifico, porque mi cadena puede tener ese caracter/byte y puede dar error al descomprimir. Deberia usar 3 bytes, porque 2 tambien puede darse la posibilidad de que mi mensaje lleve esos 2 bytes juntos. El problema es que cada mensaje ocupará 3bytes más y es mas carga de ancho de banda, y como yo no necesitaba baja latencia opté por añadirle un delay de 10 milisecconds cuando se vaya a solapar.


"lo rehíce de nuevo en adobe air porque php no soporta multihilo y me estaba encontrando con muchos problemas"
A que te referias con que php no es multihilo y air si? Eso quiere decir que php no puede enviar 2 mensajes al mismo tiempo? Que tiene que procesar primero uno y luego otro?

Por EnZo

7 de clabLevel



 

firefox
Citar            
MensajeEscrito el 28 Mar 2012 12:01 pm
Ok, hasta donde se AIR es una tecnología del lado cliente, y se usa para correr Flash y HTML con acceso al OS sin el sandbox del flash player. ¿Que es exactamente el servidor AIR? ¿Algún link donde ver info?

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 29 Mar 2012 06:55 am
Enzo, los mensajes se solapan del lado del cliente y del servidor con un servidor de sockets hecho en Air como con uno hecho en php da igual si terminas las cadenas con nueva línea o un bit 0 el listener no se ejecuta por cada línea cuando le llegan múltiples mensajes consecutivos, así que te tienes que encargar de separarlos tu haciendo lo que explique anteriormente.

En cuanto a que encriptas y comprimes los mensajes si imaginamos que después de encriptar y comprimir el siguiente símbolo backslash "/" el resultado es {ÄKá y será siempre el mismo para dicho símbolo entonces tienes que capar dicho símbolo para que solo tú puedas incluirlo como separador de cadena dentro de los mensajes enviados por el servidor, depues separas las cadenas encriptadas con split("{ÄKá") una vez separadas las cadenas descomprimes y desencriptas y tratas. No sé si te servirá pero es una idea, te las tienes que arreglar para saber por dónde cortar las cadenas tanto si están encriptadas o no, el delay que utilizas entre cadena y cadena yo creo que te servirá si la estructura es un solo cliente/servidor, pero si te encuentras con 5 o 6 o más clientes te puedes encontrar que aunque pongas un delay, si 2 o 3 clientes envían a la vez datos al server y el server los tiene que enviar de nuevo a los clientes se te solapen igual, de todas maneras aunque te funcione insertar un delay no es la solución te lo mires como te lo mires, tienes que intentar evitarlo.

Cuando digo que php no soporta multihilo me refiero a multiproceso, yo fui incapaz de mantener un bucle o proceso de escucha de entrada de sockets y a la vez tener varios procesos más independientes para controlar el tiempo transcurrido, una cuenta atrás o cualquier otra cosa. Para que me entiendas en flash puedes tener un proceso de escucha que se ejecuta cada vez que entran datos o se conecta un usuario y a la vez puedes tener otro proceso o unos cuantos como un ENTER_FRAME que vaya mostrando el tiempo transcurrido y pararlos o llamarlos en cualquier momento, en php yo no pude hacer eso o no supe cómo hacerlo, así que viendo que no podía mantener varios procesos con php busque una alternativa que fue utilizar al primer cliente que se conectara al socket server como semi servidor para que se encargara del resto de procesos y comunicarlos al socket server en php una técnica parecida utilizada con el penúltimo cod4 modern warfare que no disponía de servidores dedicados y utilizaba al propio cliente de servidor, vamos un jaleo que me perjudicaría a la larga con el avance de la programación del juego porque tienes que estar decidiendo quien hace de servidor, si se desconecta cambiar a otro cliente como servidor o si tiene mala conexión etc. además no es bueno darle ciertos controles a la aplicación de cliente y menos en flash, por esa razón al final monte el server socket en una aplicación de escritorio con Air, yo pienso que php puede servir para chats y cosas por el estilo pero para un juego de cierta complejidad no, es mejor usar otro lenguaje.

Solis ahora no recuerdo la direccion pero si miras en la web de adobe encontraras ejemplos en ingles de servidor de sockets para aplicacion de escritorio con Air

Por giskard

110 de clabLevel



Genero:Masculino  

Programador y diseñador web

msie8
Citar            
MensajeEscrito el 29 Mar 2012 01:52 pm
Es que creo que multihilo es otra cosa. Que as3 tenga eventos no significa que sea multhilo. Porque para ejecutar un evento, primero ha de ejecutar el codigo que tenga antes. Así que el problema que tu tenias de tener un bucle de carga e intentar lanzar otras tareas/funciones lo solventé con esta clase: http://code.google.com/p/dayscript-framework/source/browse/trunk/dayscript/event/EventDispatcher.class.php?r=6
Que funciona como los eventos de as3.

En cuanto a la descodificacion de mensajes, creo que añadirle un delay a los mensajes no es la mejor solucion la verdad. Cuando tenga tiempo hare mejoraré la capa de encriptacion y desencriptacion. Para separar mensajes solapados.

Por EnZo

7 de clabLevel



 

firefox
Citar            
MensajeEscrito el 30 Mar 2012 08:19 am
Interesante la clase EventDispatcher de PHP. Como siempre, el problema de PHP es la persistencia, por eso supongo que las soluciones para socket tienen a ser en Java (mas allá de la facilidad de tener el daemon corriendo en cualquiera de los dos lenguajes)
En cuanto al servidor de socket en AIR, es interesante que AIR pueda escuchar en un puerto y hacer de servidor, lo explica en este artículo: http://www.adobe.com/devnet/air/flex/articles/creating_socket_server.html . De todas formas lo veo mas para cuestiones de P2P que realmente para funcionar como servidor de sockets en entornos de producción

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 16 Abr 2012 05:18 pm
Yo antes utilizaba un NAS local para dejar las descargas. Pero luego de sufrir una perdida de datos en el server (cosa que solucione acudiendo a una empres de nombre Onretrieval en donde recuperaron los datos del disco con falla fisica) decidi montar un NAS linkeado a la nube.

De esta forma, ademas de asegurar indefinidamente la data, puedo acceder desde cualquier parte y en cualquier momento.

Saludos.

Por nuevosiglo

1 de clabLevel



 

msie
Citar            
MensajeEscrito el 25 Abr 2012 11:05 pm
Hola. me alegro de haber encontrado este hilo. Como vosotros estoy haciendo un juego multijugador con flash, pero el server, en lugar de php, estoy usando java.

No me ha pasado eso de perder mensajes. Uso la clase XMLSocket de flash en lugar de la clase Socket, pero no consigo avanzar, porque se traba, se bloquea el cliente flash. Inicialmente va todo bien, la actualización de la posición de los otros jugadores es correcta, pero al cabo de unos segundos, el jugador que estás moviendo, se bloquea, creo que es porque no le da tiempo a procesar los envios y sus recepciones.

Inicialmente enviaba un mensaje al server cada vez que se cambia la posición, y el server lo distribuía a todos (como en un chat). Como iba bien, he tratado de optimizar, minimizar, los mensajes, haciendo que el movimiento sea "prediptivo", en base al destino. Mejora, pero nada del otro mundo. Ahora tengo que se actualice la posición del jugador 3 veces/segundo, ya no es por evento de cambio de posición, sino por un timer. Pues no va.

Después de haber leido vuestros post voy a probar con la clase Socket, y ver qué tal. me gustaría que este post no muriese aquí, pues no es mucha la info que suele haber.

giskard: me alegro de leer que lograste solucionarlo, me da ánimo, que falta me hacía.

Por mano11

0 de clabLevel



 

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.