Introducción
En las próximas entradas intentaré documentar la creación de una aplicación web, que reciba actualizaciones en tiempo real, utilizando websockets.
Las tecnologías a utilizar son las siguientes:
- Python3.x
- crossbar
- Flask
- Docker
La meta para esta primera entrada es:
Tener un punto de entrada web utilizando flask, instalar crossbar para las notificaciones y poder enviar algo de algun modo y que se muestre en web sin necesidad de ajax o recargar la página.
Preparando en el entorno de desarrollo
Crear el entorno de desarrollo es relativamente sencillo gracias a que utilizaremos docker-compose
Para comenzar utilizaremos la siguiente estructura de directorios
docker-compose.yml
version: '3'
services:
web:
build: ./web
ports:
- "5000:5000"
volumes:
- ./web:/code
environment:
FLASK_ENV: development
crossbar:
image: "crossbario/crossbar"
ports:
- "8080:8080"
web/ Dockerfile
FROM python:3.7
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
web/ app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello World!\n'
requirements.txt
attrs==20.2.0
autobahn==20.7.1
Automat==20.2.0
cbor==1.0.0
cbor2==5.1.2
cffi==1.14.2
characteristic==14.3.0
click==7.1.2
constantly==15.1.0
cryptography==3.1
Flask==1.1.2
flatbuffers==1.12
hyperlink==20.0.1
idna==2.10
incremental==17.5.0
itsdangerous==1.1.0
Jinja2==2.11.2
klein==20.6.0
MarkupSafe==1.1.1
msgpack==1.0.0
py-ubjson==0.16.1
pycparser==2.20
PyHamcrest==2.0.2
six==1.15.0
Tubes==0.2.0
Twisted==20.3.0
txaio==20.4.1
ujson==3.2.0
Werkzeug==1.0.1
zope.interface==5.1.0
El siguiente paso es construir
docker-compose build
docker-compose up
Con esto ya tenemos nuestro servidor de crossbar levantado y un hello world de flask en python
Hello World en tiempo real
El siguiente paso es ingresar un template para el index y en este agregar el JS que se utiliza para conectarse al servidor de crossbar, para ello creamos un index en templates y modifcamos el el app.py
app.py
from flask import Flask
from flask import render_template
app = Flask(__name__)
@app.route('/')
def hello():
return render_template('index.html')
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="http://localhost:8080/js/autobahn.min.js"></script>
</head>
<body>
hellor world.
</body>
<script type="text/javascript">
var connection = new autobahn.Connection({url: 'ws://localhost:8080/ws', realm: 'realm1'});
connection.onopen = function (session) {
function onevent(args) {
console.log("hello")
}
session.subscribe('com.myapp.hello', onevent);
};
connection.open();
</script>
</html>
y por ultimo ocupamos quien envie la notificacion por el momento creamos otro archivo python que se encargue de este asunto
client_component_publish.py
from autobahn.twisted.component import Component, run
from autobahn.twisted.util import sleep
from twisted.internet.defer import inlineCallbacks
import os
import argparse
import six
url = u'ws://crossbar:8080/ws'
realmv = u'realm1'
print(url, realmv)
component = Component(transports=url, realm=realmv)
@component.on_join
@inlineCallbacks
def joined(session, details):
print("session ready")
counter = 0
while True:
# publish() only returns a Deferred if we asked for an acknowledgement
session.publish(u'com.myapp.hello')
counter += 1
yield sleep(1)
if __name__ == "__main__":
run([component])
Puntos a destacar
en este archivo se esta utilizando ws://crossbar:8080/ws por que internamente es el nombre de servidor. y en el index es localhost, ya que estamos accediendo desde fuera
y ejecutamos el archivo
docker exec -ti flavucros_web_1 python client_component_publish.py
Añadir nuevo comentario