2011-02-27 15 views
5

Estoy intentando crear un servidor web simple en C# en el estilo de programación de socket asíncrono. El propósito es muy estrecho: un servidor Comet (http long-polling).Servidor web: cómo analizar las solicitudes? Tokenizer de flujo asincrónico?

Tengo el servicio de Windows ejecutándose, aceptando conexiones, descargando información de solicitud a la consola y devolviendo contenido fijo simple al cliente.

Ahora, no puedo encontrar una estrategia manejable para analizar los datos de solicitud de forma asincrónica y segura. He escrito analizadores sincrónicos LL1 antes. No estoy seguro si LL1 Parser es apropiado o necesario para HTTP. No sé cómo tokenizar el flujo de entrada de forma asíncrona. Todo lo que puedo pensar es tener un buffer de entrada por cliente, leer sobre eso, luego copiarlo en un StringBuilder y revisar periódicamente para ver si tengo una solicitud completa. Pero eso parece ineficiente y podría llevar a un código de depuración/mantenimiento difícil.

Además, hay dos fases de la conexión para recibir la solicitud completa y enviar una respuesta, en este caso, después de un retraso. Una vez que la solicitud es validada y procesable, solo entonces estoy planeando inscribir la conexión en el administrador de larga duración. Sin embargo, un cliente que no funciona bien podría seguir enviando datos y llenar un búfer, por lo que creo que debo seguir supervisando y vaciando el flujo de entrada durante la fase de respuesta, ¿no?

Se agradece cualquier orientación sobre esto.

Supongo que el primer paso es saber si es posible tokenizar eficientemente una secuencia de red de forma asíncrona y sin un gran buffer intermedio. Incluso sin un analizador apropiado, los mismos desafíos de crear un tokenizador se aplican a la lectura de "líneas" de entrada a la vez, o incluso a la lectura hasta líneas dobles en blanco (un token grande). No quiero leer un byte a la vez desde la red, pero tampoco quiero leer demasiados bytes y tener que almacenarlos en algún buffer intermedio, ¿verdad?

Respuesta

2

Para HTTP la mejor manera es leer los encabezados en la memoria por completo (hasta que reciba \r\n\r\n) y luego simplemente dividir por \r\n para obtener los encabezados y cada encabezado por : para separar nombre y valor.

No es necesario utilizar un analizador complejo para eso.

+1

Gracias. ¿Cuál es una buena manera de verificar la secuencia resiliente al caso cuando se extiende a través de lecturas almacenadas en búfer? Cuando es la solicitud * ¿demasiado * larga? ¿Debo seguir vaciando la corriente de entrada después de ese punto o puedo ignorar de manera segura las entradas adicionales sin preocuparme de que el buffer se llene y afecte otras conexiones? –

Cuestiones relacionadas