Membuat layanan polling HTTP GET pada Klien Raspberry Pi

8

Saya memiliki perangkat keras berikut:

  1. 3 x Partikel Foton . Masing-masing berfungsi sebagai Server HTTP

  2. 1 x Raspberry Pi 3 yang akan berfungsi sebagai Klien HTTP

Setelah meminta GET HTTP ke Foton apa pun, API kembali:

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

Saya ingin membuat skema Polling di mana klien Raspberry Pi melakukan HTTP GET setiap 0,1 detik pada masing-masing dari 3 Server.

Saya tidak yakin apakah ada sesuatu seperti Polling HTTP dan apakah Perpustakaan Asynchronous seperti Twisted by Python harus menjadi yang akan digunakan.

Saya ingin mendapatkan saran tentang bagaimana model Multiple Server - Single Client akan berfungsi dengan HTTP?

Referensi

Setiap Photon Partikel memiliki respons JSON yang disebutkan di atas untuk Permintaan GET HTTP.

Raspberry Pi akan berfungsi sebagai Klien HTTP, berusaha mendapatkan permintaan dari masing-masing dan setiap Foton Partikel. gambar komponen dengan Pi dan tiga foton dan arah panggilan lainnya

Shan-Desai
sumber
3
Pi raspberry tidak terbatas untuk berbicara dengan satu server jarak jauh pada suatu waktu. Jika Anda dapat membuat satu klien bekerja dengan koneksi TCP yang tetap hidup, mungkin Anda dapat menyulap tiga sekaligus, baik menggunakan tiga salinan program, tiga utas, atau benar-benar menyulap deskriptor file dengan hati-hati dalam satu utas, mungkin dalam pilih besar () loop.
Chris Stratton
1
Anda dapat menggunakan browser dari Pi. Setiap tab adalah klien, masing-masing dapat mengakses server yang berbeda. Dimana masalahnya? Jika browser dapat melakukannya, kode Anda juga dapat. Sangat mudah
Mawg mengatakan mengembalikan Monica
1
Pertanyaan pengkodean mungkin lebih baik ditanyakan di stackoverflow.com Terutama karena ini adalah pertanyaan HTTP murni & perangkat independen
Mawg mengatakan mengembalikan Monica

Jawaban:

6

Saya menemukan solusi dasar yang baik untuk apa yang dimaksud @Chris Stratton dengan koneksi tcp yang tetap hidup:

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"

Anda harus membuat loop abadi yang menunggu 0,1 detik dan kemudian membuat salah satu dari langkah-langkah ini antara menghubungkan dan menutup sehingga menghubungkan hanya disebut sekali dalam memulai dan menutup hanya ketika sangat perlu untuk mematikan semuanya.

Dengan utas, begitu karya sebelumnya:

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

Sumber:

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
sumber
3

Mungkin tautan berikut dapat membantu Anda:

Contoh klien dasar: https://docs.python.org/2/library/asyncore.html#asyncore-example-basic-http-client

Contoh server echo dasar: https://docs.python.org/2/library/asyncore.html#asyncore-example-basic-echo-server

Juga, sudahkah Anda berpikir untuk menggunakan protokol UDP? mungkin lebih baik ...

Dan saya akan menyarankan tentang HTTP / 1.0, sejauh yang saya tahu, tidak wajib dalam implementasinya, untuk menjaga koneksi tetap hidup, yang didefinisikan dalam HTTP / 1.1; bagaimanapun itu tergantung pada implementasinya, bisa atau tidak bisa.


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
sumber
1
Bagaimana ini membantu semuanya? Anda tampaknya memberikan contoh sepele untuk membuat koneksi HTTP dengan cara yang sulit, tetapi apa yang ditawarkan dalam menyelesaikan masalah sebenarnya dari pertanyaan - yaitu, bagaimana hal ini membantu pengguna melakukan polling pada banyak perangkat?
Chris Stratton