Erstellen eines HTTP-GET-Abfragedienstes auf einem Raspberry Pi-Client

8

Ich habe folgende Hardware:

  1. 3 x Teilchenphotonen . Jeder dient als HTTP-Server

  2. 1 x Raspberry Pi 3 , der als HTTP-Client dient

Bei der Anforderung eines HTTP-GET an eines der Photonen gibt die API Folgendes zurück:

{
  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
      }
  }
}

Ich möchte ein Polling-Schema erstellen, bei dem der Raspberry Pi-Client alle 0,1 Sekunden auf jedem der drei Server ein HTTP-GET ausführt .

Ich bin mir nicht sicher, ob es so etwas wie HTTP-Polling gibt und ob asynchrone Bibliotheken wie Twisted by Python verwendet werden sollten.

Ich möchte einige Ratschläge dazu erhalten, wie ein Multiple Server - Single Client- Modell für HTTP funktioniert.

Referenz

Jedes Teilchenphoton hat die oben erwähnte JSON- Antwort auf eine HTTP-GET-Anfrage.

Der Raspberry Pi würde als HTTP-Client dienen und versuchen, Anforderungen von jedem einzelnen Teilchenphoton zu erhalten. Komponentenbild mit dem Pi und drei Photonen und Richtung der Ruhe ruft

Shan-Desai
quelle
3
Der Himbeer-Pi ist nicht darauf beschränkt, jeweils mit einem Remote-Server zu sprechen. Wenn Sie einen Client mit einer am Leben gehaltenen TCP-Verbindung arbeiten lassen können, können Sie vermutlich drei gleichzeitig jonglieren, entweder mit drei Kopien des Programms, drei Threads oder tatsächlich mit den Dateideskriptoren in einem einzelnen Thread, wahrscheinlich in einem große select () Schleife.
Chris Stratton
1
Sie können einen Browser von einem Pi aus verwenden. Jede Registerkarte ist ein Client, jeder kann auf einen anderen Server zugreifen. Wo ist das Problem? Wenn der Browser dies kann, kann dies auch Ihr Code. Es ist unkompliziert
Mawg sagt, dass Monica
1
Codierungsfragen werden wahrscheinlich besser auf stackoverflow.com gestellt. Zumal dies eine reine HTTP-Frage und geräteunabhängig ist
Mawg sagt, Monica

Antworten:

6

Ich habe eine gute Basislösung für das gefunden, was @Chris Stratton auf eine am Leben gehaltene TCP-Verbindung bezieht:

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"

Sie sollten eine ewige Schleife erstellen, die 0,1 Sekunden wartet und dann einen dieser Schritte zwischen Verbinden und Schließen ausführt, damit die Verbindung nur einmal beim Starten und Schließen aufgerufen wird, wenn im Extremfall alles heruntergefahren werden muss.

Mit Threads, sobald das vorherige funktioniert:

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() 

Quellen:

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

mico
quelle
3

Vielleicht können Ihnen die folgenden Links helfen:

Grundlegendes Client-Beispiel: https://docs.python.org/2/library/asyncore.html#asyncore-example-basic-http-client

Beispiel für einen einfachen Echoserver: https://docs.python.org/2/library/asyncore.html#asyncore-example-basic-echo-server

Haben Sie auch darüber nachgedacht, das UDP-Protokoll zu verwenden? es kann besser sein ...

Und ich würde raten, dass HTTP / 1.0, soweit ich weiß, in seiner Implementierung nicht obligatorisch ist, um die in HTTP / 1.1 definierten Verbindungen am Leben zu erhalten. es hängt sowieso von der Implementierung ab, die es haben kann oder nicht.


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()
sergio gonzalez collado
quelle
1
Wie hilft das überhaupt? Sie scheinen ein triviales Beispiel für die Herstellung einer HTTP-Verbindung auf die harte Tour zu liefern, aber was bietet dies zur Lösung des eigentlichen Problems der Frage - dh wie hilft dies dem Benutzer, mehrere Geräte abzufragen?
Chris Stratton