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

Python 以最少的数据使用量推送通知,python,web,push-notification,connection,network-protocols,Python,Web,Push Notification,Connection,Network Protocols,在我的项目中,我想从互联网上调用一个关于树莓圆周率的动作。不知何故: 浏览网页 点击网页上的按钮 Raspberry pi执行一个脚本 困难的部分是,树莓皮只有一个移动互联网连接,没有一个扁平化。因此,从Raspberry Pi发送和接收数据的成本很高 这就是我的问题: 我可以使用哪些技术和模式以最少的数据使用率向raspberry pi发送推送通知?首先创建或启动一些在您的RPi上接受传入连接的东西。以下示例中的一些小功能可以: #!/usr/bin/python from socket im

在我的项目中,我想从互联网上调用一个关于树莓圆周率的动作。不知何故:

  • 浏览网页
  • 点击网页上的按钮
  • Raspberry pi执行一个脚本
  • 困难的部分是,树莓皮只有一个移动互联网连接,没有一个扁平化。因此,从Raspberry Pi发送和接收数据的成本很高

    这就是我的问题:


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

    首先创建或启动一些在您的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引导期间(网络服务启动后的pref),继续并计划:

    curl https://your-server.eu/reg_ip.php > /dev/null 2>&1
    
    现在,在服务器
    yourserver.eu:443
    上,确保
    req_ip.php
    将客户机ip(客户机是您的RPi)保存在某个数据库中

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

    现在有两件事:

  • 侦听TCP套接字(在RPi上)根本不会使用任何数据,但允许在需要时输入连接

  • 如果您的IP在RPi上发生变化(例如,在移动的GSM/3G/4G网络上可能会发生变化),您需要向服务器发出另一个
    curl
    请求。然而,这可以很容易地绑定到例如
    ipmonitor
    命令,然后执行curl请求

  • tl;博士 这是你的链条:


    Pi打开一个侦听套接字->Pi连接到HTTP(S)->服务器保存IP->服务器有东西要发送时->连接到端口X上最后一个已知的IP->发送数据->关闭连接

    进一步加强 现在,HTTP头本身就相当大,事实上它是默认的78字节的包数据(TCP和IP头通常不包括在数据速率中,只有传输的数据是——在本例中是HTTP数据)。因此,您可以扩展的是,如果您也可以在服务器上使用上面的套接字的简单示例,只需使用
    na[0]
    变量并将其发送到数据库,这样您就可以在数据订阅上使用0数据速率

    只有随后作为“推送通知”从服务器应用程序发送的实际数据才会用完数据

    如果您的RPi位于基于NAT的网络(专用网络)上 由于OP获得了
    10.X.X.X
    地址,监听套接字不太可能实现这一目的

    相反,您可以做的是,您只需尝试建立一个连接并保持它的打开状态,并让服务器在有数据时通过任何打开的套接字发送数据

    以下是您如何实现这一目标的一个极其粗略的想法。
    我只是简单而愚蠢地给出了一个想法,却没有解决整个问题

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

    您可以在服务器中从数据库中获取数据,并将其发送给客户端,您可以做任何事情。既然我不知道你的目标,我就暂时不谈了

    服务器: 客户:
    Pi打开一个监听套接字->Pi连接到HTTP->服务器保存IP->服务器有东西时->连接到端口X上最后一个已知的IP->发送数据->关闭连接
    完成?打开的套接字不会永久使用数据吗?对不起,我对这件事缺乏了解-你有我可以阅读的链接吗?除非你发送数据。或者如果您将会话超时设置为短。或者使用UDP。更正,pi上的侦听套接字在连接之前从不使用数据。在电话里回答得有点快。你只需在pi上安装一个守护进程,检查IP变化,并在任何时候进行新连接。在朋友的帮助下,我做了更多的研究并意识到,至少存在一个主要问题:我的移动设备通过GSM/UMTS/LTE/等连接时无法接收外部IP。请查看我手机上的屏幕截图:@speendo不是
    213.147.163.39
    您的外部IP?感谢您的检查!我可能错了,但据我所知,这是下一个GSM天线的IP地址。@speendo我仍然认为IP将是您手机的实际外部IP,只要您打开一个插座,就可以从任何给定主机访问它。其余的应该是手机设置的虚拟接口(不知道你的操作系统、版本等,所以这只是猜测)。不过,我还包括了另一个较长的答案,用于你在NAT情况下的情况。希望这能帮助一些什么,有点基本,但应该这样做trick@speendo这是我的荣幸。我希望能成功。在我车上的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))