Creazione di un servizio di polling HTTP GET su un client Raspberry Pi


8

Ho il seguente hardware:

  1. 3 x fotoni di particelle . Ciascuno funge da server HTTP

  2. 1 x Raspberry Pi 3 che fungerà da client HTTP

Dopo aver richiesto un HTTP GET a uno dei fotoni, l'API restituisce:

{
  node: 1,
  uptime: 1234556,
  location: 'back',
  sensor: {
      Eu: {// Euler Angles from IMU
           h: 0, p: 0, r: 0
      },
      La: {// linear Acceleration values from IMU
           x: 0, y: 0, z: 0
      }
  }
}

Voglio creare uno schema di polling in cui il client Raspberry Pi esegue un HTTP GET ogni 0,1 secondi su ciascuno dei 3 server.

Non sono sicuro se ci sia qualcosa come il polling HTTP e se le librerie asincrone come Twisted by Python dovrebbero essere quelle da utilizzare.

Vorrei ottenere qualche consiglio su come funzionerebbe un modello Multiple Server - Single Client con HTTP?

Riferimento

Ogni fotone particella ha la risposta JSON sopra menzionata a una richiesta GET HTTP.

Il Raspberry Pi fungerebbe da client HTTP, cercando di ottenere richieste da tutti i fotoni delle particelle. immagine componente con il Pi e tre fotoni e direzione delle chiamate di riposo


3
Raspberry pi non si limita a parlare con un server remoto alla volta. Se riesci a far funzionare un client con una connessione TCP mantenuta in vita, presumibilmente puoi destreggiarne tre contemporaneamente, usando tre copie del programma, tre thread o manipolando i descrittori di file con cura in un singolo thread, probabilmente in un grande ciclo select ().
Chris Stratton,

1
Puoi usare un browser da un Pi. Ogni scheda è un client, ognuno può accedere a un server diverso. Dov'è il problema? Se il browser può farlo, anche il tuo codice. È semplice
Mawg dice di ripristinare Monica l'

1
Probabilmente le domande di codifica possono essere poste meglio su stackoverflow.com Soprattutto perché questa è una pura domanda HTTP e indipendente dal dispositivo
Mawg dice di reintegrare Monica il

Risposte:


6

Ho trovato una buona soluzione di base per ciò che @Chris Stratton si riferisce a una connessione tcp mantenuta in vita:

import socket

# Set up a TCP/IP socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# Connect as client to a selected server
# on a specified port
s.connect(("url_to_device_n",80))

# Protocol exchange - sends and receives
s.send("GET /answer_json HTTP/1.0\n\n")
while True:
    resp = s.recv(1024)
    if resp == "": break
    print resp, # here instead of print parse json

# Close the connection when completed
s.close()
print "\ndone"

Dovresti fare un ciclo eterno che attende 0.1s e poi compie uno di questi passaggi tra connect e close in modo che connect sia chiamato solo una volta in start e si chiuda solo quando in estrema necessità è necessario chiudere tutto.

Con i thread, una volta che il precedente funziona:

import urllib2 
from multiprocessing.dummy import Pool as ThreadPool 
import socket
import time

def sendData( urlToDevice ):
   # Set up a TCP/IP socket
   s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   s.connect(("url_to_device_n",80))
   while True:
      time.sleep(0.1)
      # Protocol exchange - sends and receives
      s.send("GET /answer_json HTTP/1.0\n\n")
      while True:
         resp = s.recv(1024)
         if resp == "": break
         print resp, # here instead of print parse json

    # Close the connection when completed
    s.close()
    print "\ndone"

#########################   
# This is main program: #
#########################

urls = [
      'url_to_device_1', 
      'url_to_device_2',
      'url_to_device_3',
      '..',
      'url_to_device_n',
      ]

# make the Pool of workers
pool = ThreadPool(n) 

# open the urls in their own threads
results = pool.map(sendData, urls)

# close the pool and wait for the work to finish 
pool.close() 
pool.join() 

fonti:

http://www.wellho.net/resources/ex.php4?item=y303/browser.py

/programming/2846653/how-to-use-threading-in-python

/programming/510348/how-can-i-make-a-time-delay-in-python


3

Forse i seguenti link possono aiutarti:

Esempio client di base: https://docs.python.org/2/library/asyncore.html#asyncore-example-basic-http-client

Esempio di server echo di base: https://docs.python.org/2/library/asyncore.html#asyncore-example-basic-echo-server

Inoltre, hai pensato di utilizzare il protocollo UDP? potrebbe essere meglio ...

E consiglierei su HTTP / 1.0, per quanto ne so, non è obbligatorio nella sua implementazione, per mantenere in vita le connessioni, che è stato definito in HTTP / 1.1; comunque dipende dall'implementazione, può avere o non può.


import asyncore, socket

class HTTPClient(asyncore.dispatcher):

    def __init__(self, host, path):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect( (host, 80) )
        self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path

    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print self.recv(8192)

    def writable(self):
        return (len(self.buffer) > 0)

    def handle_write(self):
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]


client = HTTPClient('www.python.org', '/')
asyncore.loop()

import asyncore
import socket

class EchoHandler(asyncore.dispatcher_with_send):

    def handle_read(self):
        data = self.recv(8192)
        if data:
            self.send(data)

class EchoServer(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accept(self):
        pair = self.accept()
        if pair is not None:
            sock, addr = pair
            print 'Incoming connection from %s' % repr(addr)
            handler = EchoHandler(sock)

server = EchoServer('localhost', 8080)
asyncore.loop()

1
In che modo questo aiuta le cose? Sembra che tu stia fornendo un esempio banale di come stabilire una connessione HTTP nel modo più duro, ma cosa offre ciò nel risolvere l'effettivo problema della domanda, ovvero come può aiutare l'utente a sondare più dispositivi?
Chris Stratton,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.