Haluisin tehdä javascriptillä kaksinpelin, joka kommunikoi serverin kanssa nykyisestä tilanteesta. Tarvitsen ajax tyylisiä komentoja silloin tällöin. En montaa pakettia sekunnissa. Miten minun kannattaa javaskriptin ja kokoajan pyörivän python skriptin kommunikaation tehdä? Sivut pyörivät maksetulla palvelimella.
Voit laittaa Python-ohjelmaasi HTTP-palvelimen ja käyttää tavallista XMLHttpRequestia (AJAXia). Jos pyyntöjä tulee näin aivan liikaa, voit tehdä jatkuvia yhteyksiä varten WebSocket-palvelimen ja toivoa, että käyttäjillä on aivan uusi selain.
Kyllähän tuo WebSocket toimii jo parikin vuotta vanhoilla selaimilla. Ainoa ongelma on se, että implementaatiosta on ainakin kolme hyvin erilaista implementaatiota ja että jokainen niistä on käytössä jossain selaimessa. Jo siitä syystä kannattaa unohtaa oman WS-palvelimen koodaus ja asentaa vaikka Tornado, joka on Pythonilla koodattu palvelinohjelmisto.
Olen serverillä vain yksi käyttäjä eikä minulla ole root oikeuksia eikä vapaita kuunneltavia portteja. Onnistuisiko lähettää ajax viestejä php:lle, joka välittää viestin python skriptille? Uuh..
Oletko harkinnut sitä mahdollisuutta, että Python-skriptisi ei pyörisi jatkuvasti vaan ajettaisiin aina uudestaan? Monet palvelimet tukevat myös Pythonilla tehtyjä CGI-skriptejä.
Helpointa olisi käyttää UNIX-socketteja. Niillä pääsee käytännössä samaan tulokseen kuin TCP:llä, eli Python voi kuunnella ja PHP voi ottaa siihen yhteyden.
Jos UNIX-socketit eivät jostain syystä sovi, järjestelmä voi toimia putkilla niin, että Python lukee silmukassa yhtä putkea, johon PHP ilmoittaa uusista pyynnöistä, ja jokaisella pyynnöllä on lisäksi oma väliaikainen putki itse dataa varten.
#!/bin/sh # Luodaan jono pyynnöille. # Vaihda tästä ja myöhemminkin oikeudet riittäviksi, 0600 -> 0660 -> 0666. mkfifo -m 0600 jono
<?php $id = uniqid(); ignore_user_abort(true); # Luodaan uusi putki tälle pyynnölle. posix_mkfifo($id, 0600); # tai: exec("mkfifo -m 0600 $id"); # Ilmoitus jonoon. file_put_contents("jono", "{$id}\n"); # Välitetään pyyntö ja tulostetaan vastaus. file_put_contents($id, json_encode(compact("_GET", "_POST", "_COOKIE")); header("Content-Type: application/json"); echo file_get_contents($id); # Tuhotaan putki. unlink($id);
#!/usr/bin/python3 import json # Luetaan pyyntöjä. while True: # Jonosta saadaan id eli putken nimi. for id in [s.strip() for s in open("jono", "r").readlines()]: # Luetaan pyyntö ja kirjoitetaan vastaus. pyynto = json.loads(open(id, "r").read()) vastaus = "ABC" open(id, "w").write(json.dumps(vastaus))
Saman ratkaisun voi toteuttaa myös tavallisilla tiedostoilla. Silloin ilmoitusputken lukeminen korvataan toistuvalla tiedostolistauksella. Pyyntö ja vastaus pitää laittaa eri tiedostoihin ja kaikki tiedot pitää tallentaa ensin väliaikaistiedostoon ("{$id}.tmp") ja siirtää vasta lopuksi oikealle nimelle, jottei vastapuoli vahingossa lue keskeneräistä tiedostoa. Toisaalta jos tällaiselle kikkailulinjalle pitää lähteä, saman tien voi käyttää tiedon siirtoon tietokantaa, jossa tarvittavat lukitukset tapahtuvat automaattisesti.
Kiitos avusta!
Päädyin ottamaan python cgi skriptillä socket yhteyden pyörivään python skriptiin.
Halusin pitää ristinollapelin tilanteet python skriptin muistissa, koska en aio tallentaa dataa pitkäaikaisesti ja halusin oppia jotain uutta.
Webbipalvelimen pykäämiseen ei tarvita rootteja. Esimerkiksi tuon Tornadon voi ajaa millä käyttäjällä vain, kunhan on oikeus kiinnittyä kuuntelemaan jotain porttia. (Jota ei tässä tapauksessa kuulemma ole.)
Aihe on jo aika vanha, joten et voi enää vastata siihen.