Show notice by external display [closed]

-1

I am doing a shift manager so that users arrive at a certain office, request a shift, print the ticket and wait to be called "observing" the warning screen. I have no idea (nor do I find information about it) of what to do so that from PHP a warning is printed to a screen that is not from which I am executing the program ... Could someone help me? thank you very much in advance

    
asked by Lis86 21.09.2018 в 11:02
source

2 answers

1

This can be done with a monolithic application or with an API and a frontend in independent machines. The second is easier to maintain over time but the first is easier to put together to come out with a prototype.

Let's say that your simplest architecture is a webserver and a database that contains a shift table. Each time a shift is requested, a record is inserted into the database with an ID and a "pending" status. When it is time to call the shift, it is marked with a "published" status that reflects that it appears or should appear on the screen where the turn that touches atenter is published.

The application has at least 3 endpoints :

  • GET /operar_turnos : Render a form for the operator to call the next turn
  • GET /visualizar_turno render a screen with the current shift
  • GET /pedir_turno renderiza a screen to request a new turn

Let's also say that the screen of the current turn applies an animation via jQuery when the turn changes.

To do it in PHP

Well, I would not do it in PHP. The logic of PHP is based on requests. Enter a request, pass all the related logic and optionally print something (originally PHP was just to print HTML). You could do it? Sure, you could, if the flow were:

  • User requests a ticket - > request for creation - > inserted in BBDD
  • Operator advances a turn in the queue - > request modification - > Updates the oldest turn in the "pending" state in the BBDD
  • Shift screen is asking every 5 seconds or 1 second which is the most recent turn with "published" status. - > query request - > Reading in BBDD

For this to work you have to implement a other three endpoints:

  • POST /crear_turno : receives the instruction to insert a turn with status "pending" in the database, returns the ID, is intended to be consumed by ajax
  • POST /actualizar_turno : does not print anything, only receives the instruction to update a shift with "pending" status in the database to "published" status
  • GET /turno_actual returns the current turn, is intended to be consumed by ajax

On the screen that asks for a turn:

<button id="crear_turno">Pedir Turno</button>
<script>
  jQuery('#crear_turno').on('click',function() {
     jQuery.ajax({
       url:'/crear_turno'
       type: 'POST'
     }).then(function(turno_creado) {
        // imprimo un ticket con el turno_creado
     });
  });
</script>

On the screen that updates a turn:

<button id="actualizar_turno">Actualizar Turno</button>
<script>
  jQuery('#actualizar_turno').on('click',function() {
     jQuery.ajax({
       url:'/actualizar_turno'
       type: 'POST'
     });
  });
</script>

On the screen that renders the current turn you would put:

<div id="turno_actual"></div>
<script>
  var turno_en_pantalla;
  function imprimeTurnoActual() {
     jQuery.ajax({
       url:'/turno_actual'
     }).then(function(turno_actual) {
        // necesito comparar con el turno actual y sólo
        // aplico la animación si hubo un cambio
        if(turno_actual !== turno_en_pantalla) { 
          turno_en_pantalla = turno_actual;
          jQuery('#turno_actual')
             .fadeOut(500)
             .text(turno_actual)
             .fadeIn(500);              
        }
     });
  }
  setInterval(imprimeTurnoActual,1000); // cada 1 segundo
</script>

That may work, but it has a race condition . If two operators move the turn at the same time and the consultation interval is very long, it may pass from turn 1 to turn 3 without showing that turn 2 is being called. It is also inefficient. If you ask every 0.1 seconds to mitigate the race condition, you are saturating the webserver and the bbdd. Each request opens a connection to the database and by the mere latency of connection between each layer a very short interval will fill the available connections. Let's also think that you have 5 screens showing the last turn. Each of them hits the database every 1 second.

How would you do it?

I would raise an application in nodejs using express + socket.io. Using the 3 endpoints at the beginning you have the operator screen, the screen to request a turn and the current turn screen.

But here comes the difference : you do not need the 3 additional endpoints designed to operate with ajax . Screens that render HTML establish a connection to the websockets server. This connection is persistent.

When the operator updates a turn you get the most recent turn ID and send a message to the connected clients (for what matters, the turn-based display screen). This screen has a listener that says: "if my connection to websocket sends me a message of type nuevo_turno I check the payload of the message and so I know the new turn"

With this structure you do not need the endpoints to create or update shifts. You can make the screens to request or update turns issue an event pedir_turno and actualizar_turno respectively, and let the websockets server listen to that type of messages:

io.on('connection', function (socket) {

  socket.on('pedir_turno', function () { 
    // ejecutas INSERT INTO turnos (estado, creacion) VALUES ('pendiente', now()); 
    // y obtienes el último ID insertado asignándolo a la variable "turno_creado"
    socket.broadcast.emit('turno_creado', turno_creado);
  });

  socket.on('actualizar_turno', function () { 
    // ejecutas: SELECT id from turnos WHERE estado='pendiente' ORDER BY creacion DESC limit 1; 
    // y obtienes el valor de la variable "turno_actual".
    // ejecutas: UPDATE turnos set estado='publicado' WHERE id=turno_actual
    socket.broadcast.emit('nuevo_turno', turno_actual);
  });

});

On the screen that asks for a turn:

<button id="crear_turno">Pedir Turno</button>
<script>
  var socket = io('http://localhost/');

  socket.on('turno_creado', function(turno_creado) {
        // imprimo un ticket con el turno_creado
  });

  jQuery('#crear_turno').on('click',function() {
     socket.emit('crear_turno');
  });
</script>

On the screen that updates a turn:

<button id="actualizar_turno">Actualizar Turno</button>
<script>
  var socket = io('http://localhost/');
  jQuery('#actualizar_turno').on('click',function() {
     socket.emit('actualizar_turno');
  });
</script>

On the screen that renders the current turn you would put:

<div id="turno_actual"></div>
<script>
  var socket = io('http://localhost/');
  socket.on('nuevo_turno', function (turno_actual) {
       // no necesito comparar con el valor actual 
       // porque sólo ocurre cuando hubo un cambio
       jQuery('#turno_actual') 
             .fadeOut(500)
             .text(turno_actual)
             .fadeIn(500); 
  });
</script>

And you save yourself from consulting an interval if your turn has changed. Here it is the same if you have 100 screens displaying the most recent turn. They all receive what the websockets server emits and they never hit the DB.

With this architecture you have only the 3 endpoints that render html and the rest you manage purely with websockets.

    
answered by 21.09.2018 в 13:41
0

A very simple (and a little rough) way of solving your problem, is that you have a page in your app that is to show the current info of shifts, and that you refresh that call every, for example, a second.

This can be easily implemented with html:

<META HTTP-EQUIV="REFRESH" CONTENT="1;URL=http://dominio.com/turnos.php">

With this, every second you call the web link .

Therefore, your page could be something like this (assuming you do not use a framework):

turnos.php :

<html>
<head> 
<META HTTP-EQUIV="REFRESH" CONTENT="1;URL=http://dominio.com/turnos.php">
</head>
<body>

<h1> TURNOS </h1>
<?php
 $result = array [
    "MESA 1" => "ticket a5",
    "MESA 2" => "ticket b4",
    "MESA 5" => "ticket a3"
 ];

echo "MESA  -->   TICKET<br>"; 
foreach ($result as $mesa => $ticket) {
    echo $mesa. " --> ". $ticket. "<br>";
}

It's an example, in your case the array $ result will have to come from a bbdd, and the format of html because you do it your way ...

The important thing is that in the header this is the meta clause to redirect to your website.

With this, on the screen of the users, who have to see the tickets, you open that url. The html is loaded and every 1 second it reloads itself.

    
answered by 21.09.2018 в 12:12