API Sockets para servicios agrupados antiguos


El tráfico de los sockets se factura como ancho de banda de salida. No se admite la E/S asíncrona (como Twisted en Python). App Engine solo admite la API del módulo de sockets estándar de Python para sockets salientes. Solo tienes que importar la biblioteca de sockets estándar con la siguiente instrucción:

import socket

Las bibliotecas que importan socket, como poplib o nntplib, y que no infringen las limitaciones y restricciones que se indican a continuación, deberían funcionar sin modificaciones.

Aunque el tiempo de ejecución de Python 2 admite sockets, hay ciertas limitaciones y comportamientos que debes tener en cuenta al usar sockets.

Puedes serializar un descriptor de socket y pasarlo entre instancias de App Engine, por ejemplo, como parte de una carga útil de una tarea. En este caso, puedes abrir un socket en una instancia de frontend y, a continuación, pasarlo a una instancia de backend y usarlo allí.

En las versiones del SDK anteriores a la 1.8.1, no podías llamar a las opciones get/set en los sockets. (Al hacerlo, se han producido excepciones de "Not Implemented"). Sin embargo, la API Sockets ahora lo permite.

En el caso de las opciones admitidas, las llamadas a getsockopt devolverán un valor simulado y las llamadas a setsockopt se ignorarán de forma silenciosa. Seguirán produciéndose errores en las opciones no admitidas. Las opciones admitidas son las siguientes:

  • SO_KEEPALIVE
  • SO_DEBUG
  • TCP_NODELAY
  • SO_LINGER
  • SO_OOBINLINE
  • SO_SNDBUF
  • SO_RCVBUF
  • SO_REUSEADDR

Limitaciones y restricciones

La compatibilidad con sockets en App Engine tiene las siguientes limitaciones:

  • No puedes crear un socket de escucha, solo puedes crear sockets salientes.
  • No se admite FTP.
  • De forma predeterminada, httplib se configura para usar la API urlfetch. Si necesitas usar socket para evitar los límites de urlfetch, puedes hacerlo cambiando este valor predeterminado para que httplib use sockets. Para obtener más información, consulta Hacer que httplib use sockets.
  • Solo puedes usar TCP o UDP. No se permiten protocolos arbitrarios.
  • No puedes enlazar con direcciones IP ni puertos específicos.
  • El puerto 25 (SMTP) está bloqueado, pero puedes seguir usando SMTP autenticado en el puerto de envío 587.
  • Se bloquean los intervalos de direcciones IP privadas, de difusión, de multidifusión y de Google, excepto los que se indican a continuación:

    • Google Public DNS: 8.8.8.8, 8.8.4.4, 2001:4860:4860::8888, 2001:4860:4860::8844 puerto 53
    • SMTPS de Gmail: smtp.gmail.com puertos 465 y 587
    • POP3S de Gmail: pop.gmail.com puerto 995
    • IMAPS de Gmail: imap.gmail.com puerto 993
  • Los descriptores de sockets están asociados a la aplicación de App Engine que los creó y no se pueden transferir (no los pueden usar otras aplicaciones).

  • Los sockets se pueden reclamar después de 10 minutos de inactividad. Cualquier operación de socket mantiene el socket activo durante otros 10 minutos.

  • Actualmente, socket.gethostbyaddr() no está implementado en Python. Puedes seguir usando la biblioteca estándar de Python SMTP (smtplib) para abrir una conexión:

    # Open a connection to my mail server
    s = smtplib.SMTP('smtp.mailhostingcompany.net', 587)
    

Usar sockets con el servidor de desarrollo

Puedes ejecutar y probar código usando sockets en el servidor de desarrollo sin usar ningún parámetro especial de la línea de comandos.

Usar sockets con OpenSSL

App Engine admite OpenSSL nativo de Python para el entorno de ejecución de Python 2.7. Debes configurar el archivo app.yaml para cargar la biblioteca SSL, tal como se describe en Compatibilidad con OpenSSL.

Inhabilitar la obtención de URLs para que gestione todas las solicitudes salientes

Si importas httplib, de forma predeterminada se usará la API urlfetch. Para cambiar esto y que httplib use sockets, añade la siguiente variable de entorno al archivo app.yaml:

 env_variables:
   GAE_USE_SOCKETS_HTTPLIB : 'anyvalue'

Puede sustituir anyvalue por cualquier valor, incluida una cadena vacía.

Ejemplo de App Engine que usa sockets

Para ver un ejemplo que usa sockets, consulta la aplicación de demostración de sockets en el repositorio de GitHub de Google Cloud Platform.