Demonstratie LiveView cu Python

Categorii: Programare

18-May-2020 18:00 - 34 vizionari

Dupa ce am vazut demonstratiile Phoenix.LiveView si am inteles ca actualizeaza pagina de web in timp real prin websocket, in cateva ore am imaginat o solutie cu Python.

Este vorba de o implementare naiva care actualizeaza cinci variabile JavaScript: cnt, operation, a, b si messages.

Codul este pentru serverul meu de aplicatii web, scris in Python si gasit pe github – AppServer, si consta in doua fisiere:

__init__.py – salvat in radacina modulului (extensiei) pentru AppServer:


import bottle
import threading
from bottle.ext.websocket import websocket

from appmodule import AppModule

app = AppModule()

def update_app(module_name, server_config):
    app.update(module_name, server_config)

clients = set()
lock = threading.Lock()

@app.route('/')
@app.auth('access module')
@app.view('index.tpl')
def _():
    """
        Default view
    """
    title = 'Websocket Live Demo'
    return dict(title=title)

@app.get('/live', apply=[websocket])
def _(ws):
    """
        The Live Socket
    """
    with lock:
        clients.add(ws)
    while True:
        msg = ws.receive()
        if msg is None:
            break
        print('clienti:{}, msg:{}'.format(len(clients), msg))
        for c in clients:
            c.send(msg)
    with lock:
        clients.remove(ws)

index.tpl – salvat in folderul view (folderul cu sabloane):


% include('header.tpl')

<h1>{{title}}</h1>

<button id="inc">+</button>
<button id="dec">-</button>
<span id="cnt">0</span>
<br>
<span id="operation"></span> -- <span id="a"></span> -- <span id="b"></span>
<br>
<form id="chatform">
  Name:
    <input id="name" type="text" value="name">
  Message:
    <input id="message" type="text" value="message" />
    <input type="submit" value="Send" />
</form>
<div id="messages"></div>

<script>
  var cnt = 0;

  function getWebsocketUrl(url){
    pathArray = location.href.split( "/" );
    host = pathArray[2];
    return `ws://${host}/{{module_name}}/${url}`;
  }

  $(document).ready(function() {

    if (!window.WebSocket) {
      if (window.MozWebSocket) {
        window.WebSocket = window.MozWebSocket;
      } else {
        $('#messages').append("<li>Your browser doesn't support WebSockets.</li>");
      }
    }

    ws = new WebSocket(getWebsocketUrl('live'));
    ws.onopen = function(evt) {
      $('#messages').append('<li>Connected to chat.</li>');
    }

    ws.onmessage = function(evt) {
      ret = JSON.parse(evt.data);
      for (var prop in ret) {
        if(prop == 'msg')
          $('#messages').append('<li>' + ret[prop] + '</li>');
        else{
          $('#'+prop).text(ret[prop]);
          eval(`${prop} = ${ret[prop]}`);
          }
      };
    }

    $('#chatform').submit(function() {
      var name = $('#name').val();
      var message = $('#message').val();
      var msg = `${name}: ${message}`;
      ws.send(JSON.stringify({msg:msg}));
      $('#message').val('').focus();
      return false;
    });
  
    $("#inc").off().click(function(){
      cnt = cnt + 1;
      ws.send(JSON.stringify({cnt:cnt, operation:'inc', a:100, b:200}));
    });

    $("#dec").off().click(function(){
      cnt = cnt - 1;
      ws.send(JSON.stringify({cnt:cnt, operation:'dec', a:500, b:600}));
    });

  });
</script>

% include('footer.tpl')

Comunicatia websocket in Mozilla Firefox:

livesocket

Implementarea este atat de simpla incat imi este rusine sa o public pe github, dar cat de curand voi imagina o aplicatie de chat mai complexa, care sa foloseasca un protocol compact de comunicare cu serverul prin websocket: variabilele sa aiba un id numeric si comunicatia sa fie de tip command:variabile_id:variable_value, …

Serverul de web necesita GeventWebSocketServer (pip install gevent-websocket) si extensia bottle-websocket (pip install bottle-websocket).



Ultimele pagini: RSS

Alte adrese de Internet

Categorii

Istoric


Atentie: Continutul acestui server reprezinta ideile mele si acestea pot fi gresite.