{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c00c3a39",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Ayudantía 6: Networking 🤖"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "076b5163",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Ayudantes  👾\n",
    "\n",
    "- [Clemente Campos](https://github.com/mskdancers)\n",
    "- [Patricio Hinostroza](https://github.com/Dvckhv)\n",
    "- [Julio Huerta](https://github.com/julius)\n",
    "- [Carlos Olguin](https://github.com/CarlangaUC)\n",
    "- [Catalina Miranda](https://github.com/catalinamirandah)\n",
    "- [Felipe Vidal](https://github.com/fvidalf)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63a32f43",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## ¿Qué es networking?\n",
    "\n",
    "En el mundo de las computadoras, el concepto de networking aplica a las redes de cómputo para vincular dos o más dispositivos informáticos con el propósito de compartir datos. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85ebf917",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "En Python, utilizamos la librería socket para programar con Networking.\n",
    "\n",
    "Esta librería tiene al objeto socket, encargado de manejar la comunicación entre los distintos programas."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2045f1b8",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Resumen:\n",
    "<img width=500 src=\"img/resumen.png\">"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "78ba2f77",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## DCCitas a Ciegas 🙈\n",
    "\n",
    "Los estudiantes de ingeniería suelen quejarse de que es complicado encontrar pareja en la universidad, pero dificilmente encontrarán una si se la pasan encerrados... ¡PERO TENEMOS UNA SOLUCIÓN! Deberás crear un código utilizando tus habilidades de networking para crear un chat de citas a ciegas virtual, para que así estos ingenieros no tengan que salir a conocer gente."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e3a7452",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### client.py\n",
    "\n",
    "Primero creamos el Cliente, el cual es más complejo que el Servidor, ya que posee caracteristicas de Networking y de Interfaz de Usuario. Ésto se hace debido a que el Cliente es el encargado del Backend del DCChat (donde el archivo lobby.py es su Frontend).\n",
    "\n",
    "Todo el Frontend será entregado, ustedes sólo deberán realizar la parte de Networking. Los pasos a seguir son:\n",
    "\n",
    "- `__init__(self, port, host)`: debemos tratar de conectarnos al servidor (tratamos porque no siempre se garantiza una conección éxitosa). Si la conección es exitosa seteamos el atributo `self.isConnected` como `True` e inicializamos un thread para buscar pareja con `daemon=True`, sino, nos levantará la excepción `ConnectionError` y cerraremos el socket del cliente junto con setear el atributo `self.isConnected` como `False`. Importante agregar prints ver en consola qué ocurre con nuestras conexiones.\n",
    "\n",
    "- `buscar_pareja(self)`: el loop estará corriendo hasta que encontremos alguna pareja, por ende, cuando `mensaje['type']` sea igual a 'connection', seteamos `self.isTalking` como `True`, inicializamos el Backend, comenzamos a escuchar y cortamos el loop.\n",
    "\n",
    "- `connect_to_server(self)`: en este método se realiza la conexión con el Servidor.\n",
    "\n",
    "- `listen(self)`:en este método se crea el thread encargado de escuchar al Servidor y luego hacemos que corra.\n",
    "\n",
    "- `listen_thread(self)`: cuando nuestro cliente clickea 'Next', ya no quiere seguir con la conversación, por ende, si `self.isTalking` es igual a `True`, lo seteamos como `False` y enviamos la siguiente información al servidor:\n",
    "\n",
    "        data = {\n",
    "            \"type\": \"nexted\",\n",
    "            \"username\": self.username,\n",
    "            \"data\": \"\"\n",
    "        }"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50d2faef",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### server.py\n",
    "\n",
    "- `bind_listen(self)`: asociamos el sevidor al host y puerto que le pasamos en el `__init__()`, luego indicamos que la cantidad máxima de Clientes que va a permitir que se conecten son 250.\n",
    "\n",
    "- `accept_connections(self)`: en este método se debe crear el thread encargado de aceptar las nuevas conexiones que lleguen al Servidor y finalmente hacer que el thread corra.\n",
    "\n",
    "- `accept_connections_thread(self)`: este es el metodo que ejecuta el Thread encargado de aceptar conexiones, el cual se encarga de guardar el socket que se esta conectando (en la variable client_socket) y su respectivo address. Luego se crea el thread encargado de hacer el \"match\" a dicho socket y finalmente hacemos que el thread corra."
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
