Raspberry PiクライアントでのHTTP GETポーリングサービスの作成


8

次のハードウェアがあります。

  1. 3 x パーティクルフォトン。それぞれがHTTPサーバーとして機能します

  2. HTTPクライアントとして機能する1 x Raspberry Pi 3

フォトンのいずれかに対してHTTP GETを要求すると、APIは次を返します。

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

Raspberry Piクライアントが3つのサーバーのそれぞれで0.1秒ごとにHTTP GETを実行するポーリングスキームを作成します。

HTTPポーリングのようなものがあるかどうか、PythonのTwistedのような非同期ライブラリを使用する必要があるかどうかはわかりません。

複数サーバー-単一クライアントモデルがHTTP に対してどのように機能するかについてアドバイスをもらいたいのですが。

参照

各パーティクルフォトンには、HTTP GETリクエストに対する上記のJSON応答があります。

Raspberry PiはHTTPクライアントとして機能し、あらゆるパーティクルフォトンからリクエストを取得しようとします。 Piと3つのフォトン、レストコールの方向を含むコンポーネント画像


3
ラズベリーpiは、一度に1つのリモートサーバーと通信することに限定されません。キープアライブTCP接続で1つのクライアントを機能させることができる場合は、おそらく、プログラムの3つのコピー、3つのスレッドを使用するか、実際にはおそらく1つのスレッドでファイル記述子を注意深くジャグリングして、3つ同時に操作できます。大きなselect()ループ。
Chris Stratton

1
Piからブラウザを使用できます。各タブはクライアントであり、それぞれが異なるサーバーにアクセスできます。問題はどこにありますか?ブラウザーがそれを実行できる場合、コードも実行できます。それは簡単です
Mawgはモニカを2017

1
コーディングの質問は、stackoverflow.comでおそらくもっとよく尋ねられます。これは特に純粋なHTTPの質問であり、デバイスに依存しないため、
Mawgはモニカを2017

回答:


6

私は@Chris StrattonがキープアライブTCP接続を参照するための適切な基本ソリューションを見つけました:

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"

0.1秒間待機し、接続と終了の間にこれらのステップの1つを実行する永遠のループを作成して、接続が開始時に1回だけ呼び出され、極端にすべてをシャットダウンする必要がある場合にのみ閉じるようにする必要があります。

スレッドを使用して、以前の作業が終わったら:

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

出典:

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

多分次のリンクがあなたを助けることができます:

基本的なクライアントの例: https : //docs.python.org/2/library/asyncore.html#asyncore-example-basic-http-client

基本的なエコーサーバーの例: https : //docs.python.org/2/library/asyncore.html#asyncore-example-basic-echo-server

また、UDPプロトコルの使用について考えましたか?それは良いかもしれません...

そして、私が知っている限り、HTTP / 1.1で定義された接続を維持するために、HTTP / 1.0はその実装で必須ではありません。とにかく、それは実装に依存します。


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
これはどのように物事を助けますか?あなたはHTTP接続を困難な方法で作る簡単な例を提供しているようですが、それは質問の実際の問題を解決する上で何を提供しますか、つまり、これはユーザーが複数のデバイスをポーリングするのにどのように役立ちますか?
Chris Stratton
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.