当前位置:  开发笔记 > 编程语言 > 正文

如何在Python中通过HTTP从UDP流提供数据?

如何解决《如何在Python中通过HTTP从UDP流提供数据?》经验,为你挑选了2个好方法。

我目前正致力于通过网络公开遗留系统的数据.我有一个(传统)服务器应用程序,通过UDP发送和接收数据.该软件使用UDP在(近)实时(每5-10毫秒更新)发送一组给定变量的顺序更新.因此,我不需要捕获所有UDP数据 - 检索最新更新就足够了.

为了通过Web公开这些数据,我正在考虑构建一个轻量级的Web服务器,它可以读取/写入UDP数据并通过HTTP公开这些数据.

由于我对Python有经验,我正在考虑使用它.

问题如下:我如何(连续)从UDP读取数据并通过TCP/HTTP按需发送它的快照?所以基本上,我正在尝试构建一种"UDP2HTTP"适配器来与遗留应用程序连接,这样我就不需要触及遗留代码了.

符合WSGI的解决方案将是更优选的.当然,任何提示都非常受欢迎,非常感谢!



1> Ivo van der ..:

Twisted在这里非常合适.它支持许多协议(UDP,HTTP),并且它的异步性质使得直接将UDP数据流式传输到HTTP成为可能,而无需使用(阻塞)线程代码将自己射入脚中.它也支持wsgi.



2> MattH..:

这是使用扭曲框架的快速"概念证明"应用程序.这假设传统UDP服务正在侦听localhost:8000,并将开始发送UDP数据以响应包含"发送数据"的数据报.而且数据是3个32位整数.此外,它将响应端口2080上的"HTTP GET /".

您可以从以下开始twistd -noy example.py:

example.py

from twisted.internet import protocol, defer
from twisted.application import service
from twisted.python import log
from twisted.web import resource, server as webserver

import struct

class legacyProtocol(protocol.DatagramProtocol):
    def startProtocol(self):
        self.transport.connect(self.service.legacyHost,self.service.legacyPort)
        self.sendMessage("Send me data")
    def stopProtocol(self):
        # Assume the transport is closed, do any tidying that you need to.
        return
    def datagramReceived(self,datagram,addr):
        # Inspect the datagram payload, do sanity checking.
        try:
            val1, val2, val3 = struct.unpack("!iii",datagram)
        except struct.error, err:
            # Problem unpacking data log and ignore
            log.err()
            return
        self.service.update_data(val1,val2,val3)
    def sendMessage(self,message):
        self.transport.write(message)

class legacyValues(resource.Resource):
    def __init__(self,service):
        resource.Resource.__init__(self)
        self.service=service
        self.putChild("",self)
    def render_GET(self,request):
        data = "\n".join(["
  • %s
  • " % x for x in self.service.get_data()]) return """Legacy Data

    Data

      %s
    """ % (data,) class protocolGatewayService(service.Service): def __init__(self,legacyHost,legacyPort): self.legacyHost = legacyHost # self.legacyPort = legacyPort self.udpListeningPort = None self.httpListeningPort = None self.lproto = None self.reactor = None self.data = [1,2,3] def startService(self): # called by application handling if not self.reactor: from twisted.internet import reactor self.reactor = reactor self.reactor.callWhenRunning(self.startStuff) def stopService(self): # called by application handling defers = [] if self.udpListeningPort: defers.append(defer.maybeDeferred(self.udpListeningPort.loseConnection)) if self.httpListeningPort: defers.append(defer.maybeDeferred(self.httpListeningPort.stopListening)) return defer.DeferredList(defers) def startStuff(self): # UDP legacy stuff proto = legacyProtocol() proto.service = self self.udpListeningPort = self.reactor.listenUDP(0,proto) # Website factory = webserver.Site(legacyValues(self)) self.httpListeningPort = self.reactor.listenTCP(2080,factory) def update_data(self,*args): self.data[:] = args def get_data(self): return self.data application = service.Application('LegacyGateway') services = service.IServiceCollection(application) s = protocolGatewayService('127.0.0.1',8000) s.setServiceParent(services)

    事后

    这不是WSGI设计.这样做的想法是使用be来运行这个守护程序,并在本地IP和apache或类似于代理请求上使用它的http端口.它可以为WSGI重构.这种方式更快,更容易调试.

    推荐阅读
    臭小子
    这个屌丝很懒,什么也没留下!
    DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
    Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有