在 Raspberry Pi 客户端上创建 HTTP GET 轮询服务

物联网 联网 无线的 软件
2021-06-20 02:20:47

我有以下硬件:

  1. 3 x粒子光子每个都用作 HTTP 服务器

  2. 1 x Raspberry Pi 3将用作 HTTP 客户端

向任何 Photons请求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 轮询这样的东西,以及Twisted by Python这样的异步是否应该被使用。

我想获得一些关于多服务器 - 单客户端模型如何在HTTP 上运行的建议?

参考

每个 Particle Photon 都有上面提到的对 HTTP GET 请求的JSON响应。

Raspberry Pi 将充当 HTTP 客户端,尝试从每个 Particle Photons 获取请求。 带有 Pi 和三个光子的分量图以及静止调用的方向

2个回答

对于@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 秒的永恒循环,然后在 connect 和 close 之间执行这些步骤之一,以便仅在启动时调用一次连接,并且仅在极端需要关闭所有内容时才关闭。

使用线程,一旦以前的工作:

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

https://stackoverflow.com/questions/2846653/how-to-use-threading-in-python

https://stackoverflow.com/questions/510348/how-can-i-make-a-time-delay-in-python

也许以下链接可以帮助您:

基本客户端示例: 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.0 在其实现中不是强制性的,以保持连接活跃,这是在 HTTP/1.1 中定义的;无论如何,这取决于实现,它可以有也可以没有。


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