我目前正致力于通过网络公开遗留系统的数据.我有一个(传统)服务器应用程序,通过UDP发送和接收数据.该软件使用UDP在(近)实时(每5-10毫秒更新)发送一组给定变量的顺序更新.因此,我不需要捕获所有UDP数据 - 检索最新更新就足够了.
为了通过Web公开这些数据,我正在考虑构建一个轻量级的Web服务器,它可以读取/写入UDP数据并通过HTTP公开这些数据.
由于我对Python有经验,我正在考虑使用它.
问题如下:我如何(连续)从UDP读取数据并通过TCP/HTTP按需发送它的快照?所以基本上,我正在尝试构建一种"UDP2HTTP"适配器来与遗留应用程序连接,这样我就不需要触及遗留代码了.
符合WSGI的解决方案将是更优选的.当然,任何提示都非常受欢迎,非常感谢!
这是使用扭曲框架的快速"概念证明"应用程序.这假设传统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(["<li>%s</li>" % x for x in self.service.get_data()])
return """<html><head><title>Legacy Data</title>
<body><h1>Data</h1><ul>
%s
</ul></body></html>""" % (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)
Run Code Online (Sandbox Code Playgroud)
事后
这不是WSGI设计.这样做的想法是使用be来运行这个守护程序,并在本地IP和apache或类似于代理请求上使用它的http端口.它可以为WSGI重构.这种方式更快,更容易调试.
该软件使用 UDP 以(接近)实时的方式向给定的一组变量发送顺序更新(每 5-10 毫秒更新一次)。因此,我不需要捕获所有 UDP 数据——检索最新更新就足够了
你必须做的就是这个。
步骤1。
构建一个收集 UDP 数据并将其缓存到文件中的 Python 应用程序。使用 XML、CSV 或 JSON 表示法创建文件。
它作为某种守护进程独立运行。这是你的听众或收藏家。
将文件写入一个目录,Apache 或其他 Web 服务器可以从该目录轻松下载该文件。明智地选择名称和目录路径,然后就完成了。
完毕。
如果你想要更好的结果,你可以做得更多。你不需要这样做,因为你已经完成了。
第2步。
构建一个 Web 应用程序,允许某人请求 UDP 侦听器或收集器积累的数据。
为此,请使用 Django 等 Web 框架。尽量少写。Django 可以提供由侦听器创建的平面文件。
你完成了。再次。
有些人认为关系数据库很重要。如果是这样,你可以这样做。即使你已经完成了。
步骤 3.
修改您的数据集合以创建 Django ORM 可以查询的数据库。这需要一些学习和调整才能获得整洁、简单的 ORM 模型。
然后编写最终的 Django 应用程序来提供侦听器收集并加载到 Django 数据库中的 UDP 数据。