Asynchroniczne wczytywanie obrazków

0

Nie chciałem zadawać tego pytania ale walczę już z tym klika godzin...:-)
Chciałbym wyświetlać wynik czytania pliku z serwera w jednym miejscu na stronie.
W php pracuje pętla, która czyta zawartość pliku i wyświetla jego treść ( aktualnie to "1")
Chodzi o to żeby ta treść wyświetlała się ciągle w jednym miejscu.
Myślałem, że załatwi to \r czyli powrót karetki...

<?php

echo "Wynik = ";
for ($x=1; $x<10; $x++){
$fp = fopen("kotlin/wynik.txt", "r");
$tekst = fread($fp,1);
echo "$tekst\r";
fclose($fp);
}

?>

Aktualnie wygląda to tak:
screenshot-20220529203013.png
a chciałbym żeby wyglądało tak:
Wynik = 1

Docelowo pętla ma chodzić w nieskończoność sprawdzając zawartość pliku.

Miłe podpowiedzi będą mile widziane :-)

2

A wiesz jak działa http i żądanie - odpowiedź? :) Nie możesz wprost napisać nieskończonej pętli w php i liczyć na to, że teskt sam się będzie aktualizował na stronie, przynajmniej nie jest to tak trywialne jak Ci się może wydawać. Najprościej dodać do strony skrypt JS odpytujący co interwał skrypt php o dane.

2

Zadziałałoby to, gdybyś uruchamiał ten program z konsoli, no tak

php index.php

Ale ponieważ Ty mówisz o aplikacji webowej, która składa się z klienta i servera, to musisz o tym pomyśleć w kontekście wysyłania danych przez sieć, np na socketach lub przez HTTP, i każda z tych technologii ma swoje wady i zalety.

0

Teraz potrzebuję zrobić to jak najprościej. Nic nie mówię o aplikacji webowej, :-) to pomysły innych. Moim zdaniem najprościej będzie zrobić stronę www. Pliki czytam z tego samego serwera, na którym będzie strona, więc dokładnie właśnie tak jak piszesz - index.php. Na podstawie danych z pliku ( plików), które będą zapisywane za pomocą tabletów właśnie na tym serwerze, będę wyświetlał proste informacje. Strona służy jednie jako wyświetlacz. Ponieważ nie wiem kiedy dane zostaną zapisane muszę je kontrolować niejako przez cały czas, stąd pomysł pętli, która czyta plik, w którym w pewnym momencie pojawi się zapis..np. cyfra 1. To uruchomi dalsze działanie. Będę potrzebował tez podmieniać zdjęcia na stronie i na to nie mam dobrego pomysłu. Przydał by się jakiś panel administarcyjny. Póki co po prostu mam zamiar podmieniać pliki , gdzieś bokiem, przez ftpa czy jakoś tak. ;-)
Wiem, że można lepiej ale dopiero się uczę, więc jest jak jest :-)

Najprościej dodać do strony skrypt JS odpytujący co interwał skrypt php o dane.

Tak czy siak bez pętli się nie obejdzie...chyba :-) bo jak zrealizować inaczej ten interwał ?

0

Pętla napiernioczajaca w plik, ftp, co pomysł to genialniejszy

ps. powiedz klientowi, ze fucha cię przerosła
Kotlin - przekazywanie zmiennych między funkcjami

0

ps. powiedz klientowi, ze fucha cię przerosła

Chciałbyś ;-)
Dawaj lepiej jakieś sensowniejsze rozwiązanie zamiast dołować kolegę. ;-)
A pomysły...no cóż, to moja specjalność. :-)

1

Moim zdaniem, można tak podejść do sprawy:

Po stronie serwera w skrypcie PHP powinien być jeden odczyt pliku i wyświetlenie wyniku (bez pętli). W takim razie wywołanie pliku index.php spowoduje wyświetlenie informacji aktualnej na moment uruchomienia adresu tej strony. Potem, już w HTML, umieszczasz wywołanie JavaScript, które w czasie np. 10 sekund od wyświetlenia strony wywoła ponownie adres, co spowoduje zaktualizowanie informacji.

W niektórych przeglądarkach może być problem z cache, że informacja aktualizuje się tylko przy naciśnięciu Ctrl+F5, a w pozostałych przypadkach już nie. Mozna to obejść poprzez generowanie sztucznych parametrów GET, np. index.php?dummy=123, gdzie w miejscu 123 podajesz kolejny numer, losowy ciąg znaków, lub bieżąca godzinę z sekundnikiem, przy czym bierzesz same cyfry z zapisu. Wtedy przeglądarka będzie myślała, że za kazdym razem wywołujesz inną stronę, bo jest inny adres i nie skorzysta z cache.

3
Waran3 napisał(a):

Teraz potrzebuję zrobić to jak najprościej. Nic nie mówię o aplikacji webowej, :-) to pomysły innych. Moim zdaniem najprościej będzie zrobić stronę www.

Przecież to jedno i to samo.

Siłą rzeczy masz backend i system plików tam, więc to aplikacja webowa. Ma jakieś zachowanie i integracje.

1
Waran3 napisał(a):

Teraz potrzebuję zrobić to jak najprościej. Nic nie mówię o aplikacji webowej, :-) to pomysły innych. Moim zdaniem najprościej będzie zrobić stronę www. Pliki czytam z tego samego serwera, na którym będzie strona, więc dokładnie właśnie tak jak piszesz - index.php. Na podstawie danych z pliku ( plików), które będą zapisywane za pomocą tabletów właśnie na tym serwerze, będę wyświetlał proste informacje. Strona służy jednie jako wyświetlacz. Ponieważ nie wiem kiedy dane zostaną zapisane muszę je kontrolować niejako przez cały czas, stąd pomysł pętli, która czyta plik, w którym w pewnym momencie pojawi się zapis..np. cyfra 1. To uruchomi dalsze działanie. Będę potrzebował tez podmieniać zdjęcia na stronie i na to nie mam dobrego pomysłu. Przydał by się jakiś panel administarcyjny. Póki co po prostu mam zamiar podmieniać pliki , gdzieś bokiem, przez ftpa czy jakoś tak. ;-)
Wiem, że można lepiej ale dopiero się uczę, więc jest jak jest :-)

Masz jakieś spaczone podejście, bo powiedzenie "strona służy jedynie jako wyświetlacz" to ogromne uproszczenie.

Żadna pętla Ci tu nie pomoże, bo to nie jest tak że podmianka tych tekstów czy obrazków to jest jakiś "ciągły proces", tylko każda taka zmiana musi się wiązać z nowym requestem i response'm z servera, co w php znaczy mniej więcej to że każda taka podmianka to jest uruchomienie procesu php od nowa. Więc o żadnej pętli nie może być mowy w php. Co do js, to tam pętle są blokujące (synchroniczne) więc gdybyś odpalił taki kod pętli to nigdy byś nie zobaczył wyniku. Jedyna opcja to odpalić kod asynchronicznie, np poprzez setTimeout() albo setInterval().

Najprościej dodać do strony skrypt JS odpytujący co interwał skrypt php o dane.

Tak czy siak bez pętli się nie obejdzie...chyba :-) bo jak zrealizować inaczej ten interwał ?

No np przez setInterval().

No wysyłając nowe requesty z servera do klienta, lub klienta do servera - bo strona www to dwie osobne aplikacje. To co się pokazuje w przeglądarce to jeden program, to co się dzieje na serverze to drugi program.

Mówiłem Ci już - to jak Ty sobie wyobrażasz że by to działało ma szansę tak działać w konsoli, gdybyś uruchomił plik php lokalnie.

Najprościej będzie jak po prostu od początku napiszesz wszystkie elementy jak ta aplikacja ma działać, po kolei wszystko co chcesz zrobić. I wtedy Ci powiemy jak do tego najlepiej dojść.

0

Przecież to jedno i to samo.

To nie zrozumiałem co miałeś na myśli pisząc...z konsoli.

0

Napisz dokładnie od początku do końca co ta aplikacja ma robić.

0

Dodaj cytat...Masz jakieś spaczone podejście, bo powiedzenie "strona służy jedynie jako wyświetlacz" to ogromne uproszczenie.

To nawet pewne :-)

Co do programu...
Potrzebuję Sprawdzać co jest w pliku na serwerze bo tam w pewnym momencie pojawi się wynik. Tak to jest teraz rozwiązane przeze mnie (ftp) - są głosy że tragicznie. :-) Gość na tablecie klika zapisz i w pliku wynik.txt pojawia się 1 lub 2. Ja teraz potrzebuję odczytać te wartości i w zależności od tego co tam jest, wyświetlić graficznie informacje.
Tablica w praktyce wygląda z grubsza tak:
screenshot-20220530105701.png

Podkreślam, że uczę się na tym projekcie, więc robię pewnie mnóstwo bzdur ale jak to podczas nauki...:-) więc prośba o wyrozumiałość.
To nie musi być super idealnie, w sensie że przeładować stronę można i ręcznie, przynajmniej w pierwszej wersji.

Jedyna opcja to odpalić kod asynchronicznie

No właśnie wczoraj zacząłem o tym czytać :-) ale jeszcze nie kumam. :-) Trafiłem na Node.js...ale nie wiem czy to nie za duża koparka do mojego problemu. W każdym razie jeszcze to rozkminiam.

1
Waran3 napisał(a):

Potrzebuję Sprawdzać co jest w pliku na serwerze bo tam w pewnym momencie pojawi się wynik. Tak to jest teraz rozwiązane przeze mnie (ftp) - są głosy że tragicznie. :-) Gość na tablecie klika zapisz i w pliku wynik.txt pojawia się 1 lub 2. Ja teraz potrzebuję odczytać te wartości i w zależności od tego co tam jest, wyświetlić graficznie informacje.
Tablica w praktyce wygląda z grubsza tak:
screenshot-20220530105701.png

A ten FTP to musi to być to? Czy tak sobie wymyśliłeś?

Najlepiej to byłoby to zrobić na socketach, jeśli klient (przeglądarka), ma być powiadamiana o informacjach z servera. Ale to już jest trudniejsza technologia.

Dla Ciebie polecam zrobić tak.

  1. Zrób witrynę w index.html
  2. Napisz funkcje która umie odpytać backend o dane z pliku, np przez fetch().
  3. Napisz kodzik który umie zmieniać wyświetlane dane, np poprzez innerText
  4. Dodaj w niej kodzik JavaScript który co jakiś czas (5-10 sekund, np w setTimeout()) odpytuje backend o dane z pliku

To nie musi być super idealnie, w sensie że przeładować stronę można i ręcznie, przynajmniej w pierwszej wersji.

No to jeśli chcesz przeładować stronę ręcznie, to po prostu że zrobisz

echo file_get_contents("plik.txt");

... i po sprawie. Wtedy masz jeden request, jeden response.

Jedyna opcja to odpalić kod asynchronicznie

No właśnie wczoraj zacząłem o tym czytać :-) ale jeszcze nie kumam. :-) Trafiłem na Node.js...ale nie wiem czy to nie za duża koparka do mojego problemu. W każdym razie jeszcze to rozkminiam.

Albo PHP albo node.js. Bez sensu używać obu.

3
Waran3 napisał(a):

Super! Wielkie dzięki.

Mniej więcej tak:

index.html

<html>
<body>
<span id="value"></span>

<script>
const span = document.getElementById("value");

fetchIteratively(data => {
  span.innerText = data.text;
});

function fetchIteratively(callback) {
  fetchValue(data => {
    callback(data);
    setTimeout(() => fetchIteratively(callback), 5000);
  });
}

function fetchValue(callback) {
  fetch('/values.php')
    .then(response => response.json())
    .then(data => callback(data));
}

</script>
</body>
</html>

Oraz values.php:

if (file_exists("file.txt")) {
  $file = file_get_contents("file.txt");
}
else {
  $file = "";
}

echo json_encode(['text' => $file]);

Uzyłem setTimeout() zamiast setInterval(), z dwóch powodów:

  • Po pierwsze dlatego zeby czekanie na następny call zaczęło się dopiero po skończeniu pierwszego requestu (dzięki request nie poleci częściej niż raz na 5 sekund).
  • Po drugie dlatego, żeby fail w requeście (nieudany request) zakończył ładowanie.
1

zadnych petli. odpal server na node.js ktory ci odczytuje pliki i wyswietla dane na stronie bez zadnych tam odczytywan i petli
pewnie jakies 5 linijek kodu

0

@Waran3: w pierwszym poscie napisales "Chciałbym wyświetlać wynik czytania pliku z serwera" i wlasnie na tym serwerze instalujesz node.js i odpalasz serwer ktory sprawdza zawartosc pliku i wysyla do wszystkich podlaczononych klientow. ustalasz port np 3030 i na stronie html masz szkrypt JS laczacy sie na twoja strone:3030 i czeka az serwer wysle wiadomosc i aktualizuje ten wynik co oczekujsz.

0
<script>
const span = document.getElementById("value");

fetchIteratively(data => {
  span.innerText = data.text;
});

Próbuję się odwołać do tego value w CSS,ie ale nie chce działać.:-)

<link rel="stylesheet" href="style_mk.css">

Wklejone właściwości na szybko, tak żeby tylko sprawdzić czy jest jakaś reakcja na stronie.

#value 
{
    position:absolute;
    background-color:red;
    display: inline-block;
    bottom: 107px;
    height: 70px;
    width: 200px;
    right:  370px;
    font-size: larger;
}

Działa, tylko trzeba było przeładować stronę...porządnie :-) Ctrl + F5.

0

Ze zdjęciami mi nie idzie...

<button id="get-btn" type="button"> Przycisk</button>
 <div id="blok"><img src="breck_2.jpg"></div>
var blok = document.getElementById("blok")
function zmien(src){
blok.innerHTML="<img src='"+src+"'>";
}

document.getElementById('get-btn').addEventListener('click',zmien); // przycisk wywołujacy funkcję

Strona po uruchomieniu oczywiście wyświetla breck_2.jpg ale po kliknięciu w button wyświetla się brak obrazka.
screenshot-20220602185403.png

A takie komunikaty mam na konsoli:
screenshot-20220602185519.png

0
Waran3 napisał(a):

Ze zdjęciami mi nie idzie...

<button id="get-btn" type="button"> Przycisk</button>
 <div id="blok"><img src="breck_2.jpg"></div>
var blok = document.getElementById("blok")
function zmien(src){
blok.innerHTML="<img src='"+src+"'>";
}

document.getElementById('get-btn').addEventListener('click',zmien); // przycisk wywołujacy funkcję

Strona po uruchomieniu oczywiście wyświetla breck_2.jpg ale po kliknięciu w button wyświetla się brak obrazka.
screenshot-20220602185403.png

A takie komunikaty mam na konsoli:
screenshot-20220602185519.png

Ale jaki konkretne chciałbyś tamsrc wstawić?

0

No cóż, w JS "programuję" od 3 dni " więc mam problemy z napisaniem sensownego kodu :-)

<button id="get-btn" type="button"> Przycisk</button>

<div id="img"><img id="img" src="breck_1.jpg"></div> // kompletnie się tutaj pogubiłem

var newImg = document.createElement("img")
function zmien(img){
newImg.src="breck_1.jpg"
}

0

nie wiadomo co chcesz osisagnac jesli masz guzxik zaladuj obrazek to wczytujesz plik i wyswietlasz obrazek jako base64 i dopiero potem ktos klika zapisz i go zapisujesz jako plik. bo jak sie komus nie spodoba obrazek to musisz zrobic i tak funkcje usun (obrazek z serwera i z podgladu)

0

@Waran3: no to możesz albo ustawić header odpowiedni i rypać się z tym żeby przeglądarka go nie cache'owała, albo ustawić inne nazwy plików.

No jeszcze ewentualnie możesz zrobić taki trick, że masz zmienną

let i;

i robisz potem

i = i + 1;

I jak potem wczytujesz obrazek to robisz np obrazek.jpg?x=1, obrazek.jpg?x=2, obrazek.jpg?x=3.

Rozne parametry większość przeglądarek nie uznaje jako jeden zasób, możesz tak obejść te same nazwy.

Tylko pamiętaj że cache też jest po coś. Jest po to żeby oszczędzić transfer, zwiększyć performance, i ogólnie zoptymalizować aplikacje. Psując cache takimi trickami, pozbywasz się tego.

Czy na prawdę to musi być obrazek o tej samej nazwie? Czemu?

0

Strona z grubsza będzie wyglądała tak:
screenshot-20220602201938.png

Będę potrzebował wymieniać te dwa zdjęcia podczas zawodów.
No i kombinuję jak to zrobić najlepiej i najprościej.
Spodobało mi się to asynchroniczne czytanie danych i dlatego pomyślałem o tym w kontekście zdjęć.
Oczywiście w ostateczności mogę przeładować stronę ręcznie...ale chciał bym być bardziej profi :-)

0

@Waran3: a to zawsze będzie kolekcja kilku obrazów dostarczonych przez Ciebie? Czy mogą być najróżniejsze?

0

Zdjęcia robi się zawodnikom podczas turnieju.Bo nie wiadomo kto będzie w finale. Dlatego docelowo chcę żeby to leciało bezpośrednio z telefonu

No to moim zdaniem najlepiej by było gdyby każde wrzucone zdjęcie miało inną nazwę. Albo aktualną datę albo najlepiej md5 obrazka, lub jakąś checksuma. Potem zapisałbyś nazwy obrazków które mają się wyświetlić na stronie w pliku images.json. Potem Twój js co jakiś czas by wczytywał te plik, i ładował te obrazki które są w tym pliku.

1
Waran3 napisał(a):

Brzmi nieźle...:-) Tylko nie wiem jak dać znać programowi żeby wiedział co i kiedy wyświetlić

No odpal setTimeout() co 5 sekund, wczytuj fetch("images.json"), zrób response => response.json(), pobierz adresy obrazków, i ustaw go image.src = .

0
Waran3 napisał(a):

Rozumiem, że obrazki będą miały inne adresy i że co 5 sek jest odczyt ale żeby wyświetlić odpowiednie, muszę coś zrobić...I pytanie jest co ? :-) Może kliknięcie na obrazek powodowało by wyświetlenie następnego. Chociaż wolał bym to robić gdzieś w tle. . Albo czegoś nie rozumiem co piszesz. :-)To akurat jest bardzo prawdopodobne ;-)

No przecież mówię CI:

TomRiddle napisał(a):

No odpal setTimeout() co 5 sekund, wczytuj fetch("images.json"), zrób response => response.json(), pobierz adresy obrazków, i ustaw go image.src = .

0

Najpierw masz takie pliki na serverze:

  • image1.png
    image2.png
    images.json z treścią
    {
      images: ["image1.png", "image2.png"]
    }
    

Program wczytuje plik images.json, wczytuje z niego ["image1.png", "image2.png"] i wczytuje te pliki. Odświeża potem co 5 sekund ten plik images.json, i obrazki są takie same.

Potem ktoś wchodzi, dodaje nowe dwa zdjęcia, więc pliki wyglądają tak:

  • image1.png
    image2.png
    image2.png
    image4.png
    images.json z treścią
    {
      images: ["image3.png", "image4.png"]
    }
    

Program znów wczytuje plik images.json, i wyświetla te dwa obrazki.

0

W sumie skorzystałem z poprzedniego kodu:

function fetchValue(callback) {
  fetch("images.json")
    .then(response => response.json())
    .then(data => callback(data));
    console.log(span)

}


// nie wiem jak tutaj...
fetchIteratively(data => {
  span.innerText = data.json ;
  });
{
    "images": ["breck_1.jpg", "breck_2.jpg"] 
}

Ale nie wiem co dalej, jak odczytać adresy plików.

0
Waran3 napisał(a):

Ale nie wiem co dalej, jak odczytać adresy plików.

Musisz w jakiś dowolny sposób, dać przeglądarce znać że Twój obrazek się zmienił:

  • Sposób #1: Albo wysłać header'y, prosząc o nie cache'owanie obrazków (tylko wtedy praktycznie wyłączasz ich cache, i będą często ładowane te same dane)

  • Sposób #2: Albo załadować obrazki z parametrami

  • Sposób #3: Albo nadać obrazkom różne nazwy - to jest najlepsze wyjście

    Ale jeśli nadasz im różne nazwy, to musisz je jakoś wczytać - te nazwy. Tutaj wkracza JSON, zapisujesz w nim nazwy obrazków, potem strona wczytuje ten plik, mówi: "oho, takie są nowe nazwy obrazków", i wczytuje je.

Nie wiem jak na to wpadłeś, ale umieszczanie na serverze różnych obrazków pod tą samą nazwą, to proszenie się o kłopoty. Można by to zrobić, gdybyś chciał zmienić coś nieistotnego, jakiś cień, metodę kompresji, format - bo wtedy użytkownik strony i tak nie zauważy różnicy. Ale Ty chcesz wyświetlić różne obrazki, musisz więc w aktywny sposób zadziałać żeby je podmienić, jednym z trzech sposobów które wymieniłem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1