以最少的数据使用推送通知

时间:2016-09-26 09:42:09

标签: python web push-notification connection network-protocols

在我的项目中,我想通过Internet调用Raspberry Pi上的操作。不知怎的,那样:

  1. 访问网页
  2. 点击网页上的按钮
  3. Raspberry pi执行脚本
  4. 困难的部分是,树莓派只有一个移动的互联网连接没有扁平的。因此,从/向Raspberry Pi发送和接收数据的成本很高。

    所以这是我的问题:

    我可以使用哪些技术和模式以最少的数据用量向Rasberry pi 发送推送通知

1 个答案:

答案 0 :(得分:1)

首先创建或启动接受RPi传入连接的内容。像下面的例子那样小:

#!/usr/bin/python
from socket import *
s = socket()
s.bind(('', 8001))
s.listen(4)
while 1:
    ns, na = s.accept()
    print(na,'sent you:',ns.recv(8192))

现在,上面的例子只会在8001上打开一个端口,然后打印发送给它的其他发送内容。

在服务器端,我建议您设置一个Web服务器或其他易于访问的东西,可以将IP存储在数据库/寄存器中。

然后,在您的RPi启动期间(网络服务启动后的首选项)继续并安排:

curl https://your-server.eu/reg_ip.php > /dev/null 2>&1

现在,在服务器your-server.eu:443上,确保req_ip.php将客户端IP(客户端是您的RPi)保存在某个数据库中。

现在,您需要发送PUSH通知的应用程序可以查找数据库中当前的客户端IP,并尝试连接到这些IP上的端口8001并发送您需要的任何数据。 / p>

现在有两件事:

  1. 侦听TCP套接字(在RPi上)根本不会消耗任何数据,但会在需要时允许连接。

  2. 如果您的IP更改了RPi(例如,它可能会在移动的GSM / 3G / 4G网络上),您需要向服务器发送另一个curl请求。然而,这很容易绑定到例如ip monitor命令并执行curl请求。

  3. TL;博士

    这是你的链条:

    Pi opens a listening socket -> Pi connects to HTTP(S) -> servers saves IP -> when server has something to send -> connect to last known IP on port X -> send data -> close connection

    进一步加强

    现在,单独的HTTP标头非常大,实际上它是默认的78字节的数据包数据(TCP和IP标头通常不包含在数据速率中,只有传输的数据是 - 在这种情况下是HTTP数据。 )。所以你可以扩展的是,如果你可以在服务器上使用上面的套接字的简单示例,只需取na[0]变量并将其发送到数据库,这样就可以使用字面上的0数据速率您的数据订阅。

    只有稍后从服务器应用程序发送的实际数据作为“PUSH通知”才会使用数据。

    如果您的RPi位于基于NAT的网络(专用网络)

    看到OP获得10.X.X.X地址,侦听套接字不太可能发挥作用。

    相反,你可以做的就是你可以简单地尝试建立连接并使其保持打开状态,让服务器在有数据时通过任何打开的套接字发送数据。

    这是一个非常粗略的想法,你将如何实现它 我保持简单而愚蠢只是为了在不解决整个问题的情况下提出一个想法。

    同样,在您通过频道实际发送数据之前,客户端(RPi)和服务器之间的开放套接字不会用完任何数据。

    您可以在服务器中从要发送给客户端的数据库中获取数据,您可以做任何事情。由于我不知道你的目标,我将暂时保留它。

    服务器:

    #!/usr/bin/python
    from socket import *
    from threading import *
    from time import time, sleep
    from random import randint
    
    class ClientThread(Thread)
        def __init__(self, clients):
            self.clients = clients
            self.messages = []
            Thread.__init__(self)
            self.start()
    
        def notify(self, message):
            if type(message) is str: message = bytes(message, 'UTF-8')
            self.messages.append(message)
    
        def run(self):
            while 1:
                if len(self.messages) > 0:
                    m = self.messages.pop(0)
                    for client in self.clients:
                        self.clients[client]['sock'].send(m)
    
    class RandomMessageGenerator(Thread):
        def __init__(self, notify_func):
            self.notify_func = notify_func
            self.last = time()
            Thread.__init__(self)
            self.start()
    
        def run(self):
            while 1:
                self.notify_func('Time since last update: ' + str(time() - self.last))
                self.last = time()
                sleep(randint(0,30))
    
    client_list = {}
    client_thread_handle = ClientThread(client_list)
    random_generator = RandomMessageGenerator(client_thread_handle.nofity)
    
    s = socket()
    s.bind(('', 8001))
    s.listen(4)
    
    while 1:
        ns, na = s.accept()
        client_list[na] = {'sock' : 'ns'}
    

    客户端:

    from socket import *
    s = socket()
    s.connect(('server', 8001))
    while 1:
        print(s.recv(8192))