Pagina 1 di 1
[PHP] socket/websocket astrazione e chiamata indiretta
Inviato: venerdì 29 maggio 2015, 14:16
da SuperStep
Salve,
mi trovo a dover implementare un protocollo application-level che deve essere compatibile con socket e websocket. Inoltre se possibile dovrebbe girare sotto php e darmi la possibilita' di accedere alle varie connessioni indirettamente da altre pagine.
Mi spiego meglio:
ho varie funzioni che eseguono dei comandi che fanno qualcosa:
esempio:
* aggiungere un modello al sistema
* eliminare un modello dal sistema
* aggiornare un modello nel sistema
Le solite operazioni CRUD, ma anche qualche operazione indipendente dai modelli.
Quello che vorrei fare e':
Implementare i client (Quello web e quello non) che oltre a poter fare le operazioni, aprano anche una comunicazione su questo mio programma. ed in qualche modo poter intercettare le connessioni aperte e poter scrivere sulle socket indipendentemente se siano websocket o non.
una cosa del genere:
Codice: Seleziona tutto
public function createModelX($arguments = []) {
// codice per crearlo
$clients = SocketClientConnection::all();
foreach($clients as $client) {
if($client->havePermissionOnModel('model_name') {
$client->send(ModelXEventResponse::created($theModelCreated));
}
}
}
ovviamente devo implementare alcune cose particolari per cui quando c'e' l'autenticazione questa venga fatta anche sulle socket, per cui posso semplicemente richiamare il metodo php (per questo sarebbe meglio php), ed all'interno posso anche accedere a quali permessi abbia sui modelli.
Quello che proprio non so come implementare e' la possibilita' di far vedere al mio codice del webserver dei dati salvati da un altro codice che gira separatamente (una sorta di IPC).
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: martedì 2 giugno 2015, 5:32
da eaghezzi
se fai tutto tramite php uno script non web sempre attivo che rimane in ascolto dovresti poter gestire tutti i tipi di comunicazione
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: martedì 2 giugno 2015, 18:35
da SuperStep
e' il come che mi manca.
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: mercoledì 3 giugno 2015, 6:06
da eaghezzi
lato server apri un socket (su ip pubblico o lan ma raggiungibile dall'esterno) e stai in ascolto
crei poi uno o più client a seconda del tipo di comunicazione che devi ottenere
supponiamo devi mandare il comando create template da una pagina web
crei un client ajax-socket
riceve la richiesta ajax dalla pagina web
apre un sokcet verso il socket server
invia la richiesta attende la risposta
chiude la chiamata ajax e chiude il socket
stesso discorso se un'altra procedura deve comunicare
in sostanza crei uno o più client socket a seconda di come li vuoi istanziare
trovi un esempio di semplice server socket
qui
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: mercoledì 3 giugno 2015, 10:06
da SuperStep
non mi sono spiegato.
Voglio che ci siano delle socket aperte sul server.
Ad ogni connessione ed autenticazione viene salvato la coppia Socket - Utente da qualche parte.
In Un'altra parte dell'applicazione da una richiesta http mandata da qualcuno (chiunque non solo l'host che ha aperto la socket), voglio fare in modo che in quella "pagina" posso ripescare la socket aperta e mandare un messaggio tramite quella.
Faccio un esempio più specifico:
Classe che gestisce le mie (web)socket
Codice: Seleziona tutto
class CustomServerSocket extends SocketServer {
private static $socketClients = [];
public static function onConnect($socketClient){ ... }
public static function onDisconnect($socketClient){ ... }
public static function onMessage($socketClient, $socketProtocolReceivedMessage){ ... }
public static function sendMessage($socketClient, $socketProtocolSendMessage){ ... }
public static function retriveSocketByUserId($user){ ... }
public static function socketsConnected(){ ... }
}
questa è la classe per gestire i socketClient
Codice: Seleziona tutto
class SocketClientConnextion extends Socket {
private $user = null;
private function auth($username, $password) { .... }
private function xxx($a[, $b[, ...]]){ ... }
}
adesso, quello che vorrei fare è:
Avere "un'istanza del server sopra e le istanze delle connessioni"
in modo che quando sono su una pagina php possa fare una cosa del genere:
Codice: Seleziona tutto
<?php
if(!empty(CustomServerSocket::socketsConnected()){
if($userSocket = CustomServerSocket::retriveSocketsByUserId(7)){
CustomServerSocket::sendMessage($userSocket, new ProtocolSendMessage(ProtocolSendMessage::$type_a, ['x','y','z']);
}
}
quello che mi manca è: dal momento che server web ed il server socket, sono processi separati, non possono comunicare. Quindi come faccio io a prelevare una sua istanza? Ma soprattutto, dal momento che se volessi salvare le socket tramite il meccanismo delle sessioni, queste sarebbero suddivise per sessione. Come faccio io ad agglomerare il tutto?
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: mercoledì 3 giugno 2015, 20:58
da Zoff
Non mi è chiaro cosa intendi con la frase citata. WebSocket è Socket-based, quindi se implementi un websocket server dai automaticamente il supporto alle connessioni socket che utilizzano il formato websocket.
A quel punto puoi usare tranquillamente Ratchet:
http://socketo.me/
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 2:31
da SuperStep
Scusate forse non mi esprimo bene.
Quando creo un ServerSocket con php, devo lanciare in esecuzione lo script al fine di rimanere in ascolto per le connessioni in entrata.
Supponiamo per un attimo di avere gia' questo codice pronto.
Adesso dall'altra parte ho un'applicazione web che gira sotto apache. Ad una determinata richiesta HTTP devo prendere le Socket collegate al Server per poter spedire un messaggio.
Come faccio a condividere "GLI OGGETTI" (Socket client) che ServerSocket salva avviati nel mio script.
Con la mia applicazione che gira sotto il webserver?
Cioe', quello che mi manca e' proprio questo, trovare un modo per condividere le "connessioni" (Socket Client) tra uno script avviato da terminale e il mio webserver. Non condividono la stessa memoria, essendo istanze di processi diversi. Quindi come faccio a farli comunicare?
[EDIT]
lo scopo se non si fosse capito, e' quello di comunicare una "notifica" ai client connessi quando una certa risorsa http viene "toccata".
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 4:28
da eaghezzi
manteniamo per un attimo la logica del server socket 'socket_server' (attenzione non necessariamente web socket.
ad ogni connessione client assegniamo uno stato, oggetto,id ...che il client memorizza per successive comunicazioni
il server_socket mantiene lo stato logico di tutte le connessioni
ora il flusso che mi sono immaginato
un utente web prima visita carica la pagina di login
compila il form fa il post dei dati per l'autentica per es. utente_uno
che si suppone attivi la comunicazione tra 'utente' e socket server
lo script php che gestisce il post si autentica su socket_server e riceve il suo stato id,oggetto .... che memorizza nella propria session (che è quella del web)
ogni pagina che visita utente_uno controlli la sessione interroghi nuovamente il socket_server con l'id i utente_uno e ricevi eventuali messaggi
parallelamente un'altro processo può per controllare lo stato di un'altra risorsa per es. l'up di un file questo processo notifica l'evento a socket_server
che a sua volta lo notificherà ai client interesssati.
la grossa limitazione di questa logica è che la comunicazione ai client è asincrona ed avviene solo tramite poll del client
detto questo se serve una comunicazione sincrona ogni volta che generi una pagina di un utente autenticato gli passi il suo id ed apri immediatamente un web socket che resta in ascolto
a questo punto la connessione a server_socket non viene chiusa e puoi notificare da server ai client tutti gli eventi necessari
in un applicativo gestionale fatto anni fa quando non c'erano i web socket e l'esigenza era una banale chat tra gli utenti ho fatto tutta la comunicazione asincrona tramite poll con ajax e devo dire che il risultato non perfetto ma accettabile e funzionale allo scopo.
oggi se dovessi rifare il sistema tenendo presente che a me piace mantenere la logica della singola responsabilità di un oggetto/sistema/modulo lo rifarei così
server_socket un processo che tramite tcp ip ha il compito di coordinare le comunicazioni con vari client una sorta di queue server
vari sotto processi (od uno solo) che monitorano le risorse richieste
per es. l'arrivo di una mail notifica l'evento al socket_server che il compito di notificarlo a sua volta al client appropriato (se connesso o quando si connetterà)
mantenendo questa logica se il carico web fosse elevato io farei così
farei un'altro server socket questa volta dedicato al web in cui centralizzo tutte le comunicazioni tuttto tramite web socket
il web_socket_Server sarà a sua volta client di socket_server in quanto il suo compito è esclusivamente quello di gestire le comunicazioni con i client web.
questi sono solo suggerimenti basati sull'esperienza sul campo la soluzione migliore si progetta sempre quando tutti requisiti sono esplicitati
e si ha almeno un ordine di grandezza delle dimensioni del sistema
quanti sotto processi di controllo/monitoraggio ci sono
quanti utenti web contemporanei sono stimati ?
quanti connessioni contemporanee sono previste , il flusso di comunicazioni ...
l'esempio fatto era inserito in un gestionale con mediamente 100 utenti attivi su intranet quindi rete privilegiata ed affidabile
le notifiche seppur fatte in polling erano quasi in tempo reale, cmq sufficientemente veloci per lo scopo.
un esempio :
capitava spesso che un utente di un ufficio dovesse accedere ad una risorsa di cui non aveva i permessi
l'evento veniva notificato al suo responsabile che consentiva un accesso temporaneo tramite le proprie credenziali
il socket_server gestiva tutta la comunicazione quasi in tempo reale cmq con un ritardo di pochi secondi.
hth.
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 7:57
da SuperStep
non vorrei usare ajax in poll continuo per evitare spreco di risorse in quanto l'utilizzo dell'applicazione (per sua natura) e' molto costoso e le risorse non sono nemmeno troppe.
L'applicazione non girera' in cluster, quindi Il WebServer ed Il mio SocketServer risiedono sulla stessa macchina.
Gli utenti che hanno la comunicazione sulle socket aperte non sono molti, (siamo su un intervallo che varia fra le 5 e le 30 entita'), ma il consumo potrebbe risultare elevato in quanto l'applicazione e' stata pensata per fornire un consumo sia ad un essere umano, che ad un'altra macchina tramite apposite API (Socket/HTTP).
Il sistema non puo' prevedere ritardi dell'ordine di oltre 1 secondo, quindi anche per questo non utilizzerei un poll ajax.
io pero' ancora non riesco a capire come fare questa cosa, faccio un grafico va
Codice: Seleziona tutto
WebServer - Apache2 + SocketServer - php
|
onSpecificHttpRequest | socketsClient[ client1, client2, client3 ]
| | ^
| | |
+->get(SocketServer::all())-----+
|
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 9:54
da Zoff
Non mi è troppo chiaro il problema vero e proprio.
Perché dovrebbe essere il serve apache ad inviare al richiesta? È sufficiente che lo script che gira su Apache invii a SocketServer una richiesta che segnala il "tocco" della risorsa e il SocketServer, che conosce già tutti i client connessi, propaga la notifica. Che tra l'altro è il normale comportamento di un websocket server.
Rinnovo il consiglio di utilizzare Ratchet, è praticamente già pronto: Vedi l'esempio di push notification:
http://www.socketo.me/docs/push
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 17:42
da SuperStep
Quindi sostanzialmente dovrebbe essere una cosa del genere
Codice: Seleziona tutto
WebServer -----> SocketServer <-----> SocketClient(s)
ho capito bene?
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 17:57
da Zoff
Sì, ma se guardi l'ultimo link mi sembrano piu' chiari i loro grafici.
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 18:34
da SuperStep
Si ho guardato tutti i grafici presenti in tutorials e mi sono fatto un'idea. Solo che la comunicazione non va solo verso client che hanno le websocket, ma client che utilizzano anche socket normali.
Faccio un esempio:
La mia applicazione prevedere di accedere ad elementi tramite REST + CRUD. Ad ogni azione corrisponde un comando, ed ogni comando ha un handler che se specificato dovrebbe mandare l'evento ai client connessi.
Adesso i client sono di varia natura: "browser, App Android, Eseguibili binari su dispositivi embedded che si interfacciano con hardware di sistemi automatici (cancelli, porte, ...)".
Tutte queste Applicazioni si autorizzano sul sistema tramite Http e sono degli utenti nel sistema che posseggono determinati privilegi e filtrano determinati messaggi.
Adesso, Quando l'applicazione parte (quelle automatiche) fanno l'autenticazione su http e dovrebbero farla anche per le socket.
La logica e' la seguente:
Per Fare un'azione REST usano http.
Quando un altro fa un'azione REST ricevono l'evento su socket/websocket.
Volevo cercare di implementare un protocollo application-level in cui sia nelle socket che nelle websocket il "messageText" sia un documento XML descrittivo di cosa sia successo e chi e' stato.
Quindi quando un Utente si autentica, dopo apre anche una Socket sul ServerSocket.
Quando un client fa un'operazione REST, il webserver notifica al SocketServer che costruisce i messaggi a seconda del client e li spedisce per ogni client.
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 19:18
da Zoff
Ribadisco che le websocket sono solo un protocollo che si appoggia a HTTP, quindi TCP, quindi "girano" su socket, quindi basta implementare il protocollo websocket su socket.
Se si ha paura dell'overhead dell'implementazione del protocollo websocket per dispositivi embedded (sinceramente prima di scartarlo due conti li farei comunque) potete comunque predere spunto dall'esempio di Ratchet visto che utilizza ZeroMQ che può tornarvi utile.
Il punto base è che le socket aperte sono risorse allocate non "trasportabili", non puoi spostare una socket (ricordo che in *nix a bassso livello non è altro che un filedescriptor) da un sistema ad un altro.
Per questo motivo il sistema che si occupa di stabilire le connessioni deve essere quello che le gestisce.
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: giovedì 4 giugno 2015, 21:53
da SuperStep
no questa cosa mi piace.
In particolare devo farlo per applicativi in C++ e Java.
Conosci qualcosa di già pronto per non partire da zero?
Re: [PHP] socket/websocket astrazione e chiamata indiretta
Inviato: sabato 6 giugno 2015, 10:42
da Zoff
Già pronto sotto quale aspetto? WebSocket fuori da un browser?
C++/QT:
http://doc.qt.io/qt-5/qtwebsockets-ssle ... ample.html
Java:
https://tyrus.java.net/