当前位置: 首页 > 知识库问答 >
问题:

使用Python Twisted和Autobahn通过WebSocket从Matlab发送JSON数据

孟和怡
2023-03-14
clear all
close all

python = '/usr/local/bin/python'
bc = '/Users/palmerc/broadcast_client.py'
i = uint32(1)

encoder = org.apache.commons.codec.binary.Base64
while true
    tic;
    packet = rand(100, 100);
    json_packet = uint8(savejson('', packet));
    compressed = CompressLib.compress(json_packet);
    b64 = char(encoder.encode(compressed));
    message = sprintf('%s %s %s', python, bc, b64);
    status = system(message);

    i = i + 1;
    toc;
end
#!/usr/bin/env python

import sys
from twisted.internet import reactor
from txjsonrpc.web.jsonrpc import Proxy


class BroadcastClient():

    def __init__(self, server=None):
        self.proxy = Proxy(server)

    def errorMessage(self, value):
        print 'Error ', value

    def sendMessage(self, message):
        rc = self.proxy.callRemote('broadcastMessage', message).addCallback(lambda _: reactor.stop())
        rc.addErrback(self.errorMessage)


def main(cli_arguments):
    if len(cli_arguments) > 1:
        message = cli_arguments[1]
        broadcastClient = BroadcastClient('http://127.0.0.1:7080/')
        broadcastClient.sendMessage(message)
        reactor.run()

if __name__ == '__main__':
    main(sys.argv)

服务器在7080上提供一个RPC客户机,在8080上提供一个web客户机,在9080上提供一个WebSocket,使用TXJSONRPC、Twisted和Autobahn。Autobahn Web客户端对调试很有用,应该与服务器代码放在同一个目录中。

#!/usr/bin/env python

import sys

from twisted.internet import reactor
from twisted.python import log
from twisted.web.server import Site
from twisted.web.static import File
from txjsonrpc.web import jsonrpc

from autobahn.twisted.websocket import WebSocketServerFactory, \
    WebSocketServerProtocol, \
    listenWS


class BroadcastServerProtocol(WebSocketServerProtocol):

    def onOpen(self):
        self.factory.registerClient(self)

    def onMessage(self, payload, isBinary):
        if not isBinary:
            message = "{} from {}".format(payload.decode('utf8'), self.peer)
            self.factory.broadcastMessage(message)

    def connectionLost(self, reason):
        WebSocketServerProtocol.connectionLost(self, reason)
        self.factory.unregisterClient(self)


class BroadcastServerFactory(WebSocketServerFactory):

    """
    Simple broadcast server broadcasting any message it receives to all
    currently connected clients.
    """

    def __init__(self, url, debug=False, debugCodePaths=False):
        WebSocketServerFactory.__init__(self, url, debug=debug, debugCodePaths=debugCodePaths)
        self.clients = []

    def registerClient(self, client):
        if client not in self.clients:
            print("registered client {}".format(client.peer))
            self.clients.append(client)

    def unregisterClient(self, client):
        if client in self.clients:
            print("unregistered client {}".format(client.peer))
            self.clients.remove(client)

    def broadcastMessage(self, message):
        print("broadcasting message '{}' ..".format(message))
        for client in self.clients:
            client.sendMessage(message.encode('utf8'))
            print("message sent to {}".format(client.peer))


class BroadcastPreparedServerFactory(BroadcastServerFactory):

    """
    Functionally same as above, but optimized broadcast using
    prepareMessage and sendPreparedMessage.
    """

    def broadcastMessage(self, message):
        print("broadcasting prepared message '{}' ..".format(message))
        preparedMessage = self.prepareMessage(message.encode('utf8'), isBinary=False)
        for client in self.clients:
            client.sendPreparedMessage(preparedMessage)
            print("prepared message sent to {}".format(client.peer))


class MatlabClient(jsonrpc.JSONRPC):

    factory = None

    def jsonrpc_broadcastMessage(self, message):
        if self.factory is not None:
            print self.factory.broadcastMessage(message)


if __name__ == '__main__':

    if len(sys.argv) > 1 and sys.argv[1] == 'debug':
        log.startLogging(sys.stdout)
        debug = True
    else:
        debug = False
    factory = BroadcastPreparedServerFactory(u"ws://127.0.0.1:9000",
                                             debug=debug,
                                             debugCodePaths=debug)

    factory.protocol = BroadcastServerProtocol
    listenWS(factory)

    matlab = MatlabClient()
    matlab.factory = factory
    reactor.listenTCP(7080, Site(matlab))

    webdir = File(".")
    web = Site(webdir)
    reactor.listenTCP(8080, web)

    reactor.run()

首先要注意的是,如果在Matlab中使用python有问题,您需要确保使用pyversion命令指向系统上的python的正确版本,并且可以使用pyversion('/path/to/python')进行更正

clear all
close all

i = uint32(1)

while true
    tic;
    packet = rand(100, 100);
    json_packet = uint8(savejson('', packet));
    compressed = CompressLib.compress(json_packet);
    b64 = char(encoder.encode(compressed));
    bc.sendMessage(py.str(b64.'));
    py.twisted.internet.reactor.run % This won't work.

    i = i + 1;
    toc;
end

另一个尝试涉及到使用MATLAB的webwrite向服务器发布。事实证明,webwrite只需传递正确的weboptions即可将数据转换为JSON。

options = weboptions('MediaType', 'application/json');
data = struct('Matrix', rand(100, 100));
webwrite(server, data, options);

如何调用bc.sendmessage,使其能够正确地运行reactor或以另一种更快的方式解决此问题?

共有1个答案

艾泉
2023-03-14

首先,您需要确保使用的是正确的python二进制文件。例如,在Mac上,您可能使用的是系统标准版本,而不是Homebrew安装的版本。使用以下方法检查python安装的位置:

pyversion

您可以使用以下方法将Matlab指向正确的版本:

pyversion('path/to/python')

这可能需要重新启动Python。

server = 'http://127.0.0.1:7080/update.json';
headers = py.dict(pyargs('Charset','UTF-8','Content-Type','application/json'));
while true
    tic;
    packet = rand(100, 100);
    json_packet = savejson('', packet);
    r = py.requests.post(server, pyargs('data', json_packet, 'headers', headers));
    toc;
end
import sys

from twisted.internet import reactor
from twisted.python import log
from twisted.web.resource import Resource
from twisted.web.server import Site
from twisted.web.static import File

from autobahn.twisted.websocket import WebSocketServerFactory, \
    WebSocketServerProtocol, \
    listenWS


class BroadcastServerProtocol(WebSocketServerProtocol):

    def onOpen(self):
        self.factory.registerClient(self)

    def onMessage(self, payload, isBinary):
        if not isBinary:
            message = "{} from {}".format(payload.decode('utf8'), self.peer)
            self.factory.broadcastMessage(message)

    def connectionLost(self, reason):
        WebSocketServerProtocol.connectionLost(self, reason)
        self.factory.unregisterClient(self)


class BroadcastServerFactory(WebSocketServerFactory):

    def __init__(self, url, debug=False, debugCodePaths=False):
        WebSocketServerFactory.__init__(self, url, debug=debug, debugCodePaths=debugCodePaths)
        self.clients = []

    def registerClient(self, client):
        if client not in self.clients:
            print("registered client {}".format(client.peer))
            self.clients.append(client)

    def unregisterClient(self, client):
        if client in self.clients:
            print("unregistered client {}".format(client.peer))
            self.clients.remove(client)

    def broadcastMessage(self, message):
        for client in self.clients:
            client.sendMessage(message.encode('utf8'))


class BroadcastPreparedServerFactory(BroadcastServerFactory):

    def broadcastMessage(self, message, isBinary=False):
        if isBinary is True:
            message = message.encode('utf8')
        preparedMessage = self.prepareMessage(message, isBinary=isBinary)
        for client in self.clients:
            client.sendPreparedMessage(preparedMessage)


class WebClient(Resource):

    webSocket = None

    def render_POST(self, request):
        self.webSocket.broadcastMessage(request.content.read())

        return 'OK'


if __name__ == '__main__':

    if len(sys.argv) > 1 and sys.argv[1] == 'debug':
        log.startLogging(sys.stdout)
        debug = True
    else:
        debug = False
    factory = BroadcastPreparedServerFactory(u"ws://127.0.0.1:9000",
                                             debug=debug,
                                             debugCodePaths=debug)

    factory.protocol = BroadcastServerProtocol
    listenWS(factory)

    root = Resource()
    webClient = WebClient()
    webClient.webSocket = factory
    root.putChild('update.json', webClient)
    webFactory = Site(root)
    reactor.listenTCP(7080, webFactory)

    webdir = File(".")
    web = Site(webdir)
    reactor.listenTCP(8080, web)

    reactor.run()
 类似资料:
  • ap.sendSocketMessage(OPTION, CALLBACK) 通过 WebSocket 连接发送数据,需要先 ap.connectSocket,并在 ap.onSocketOpen 回调之后才能发送。 OPTION 参数说明 名称 类型 必选 描述 data String/ArrayBuffer 否 请求的参数 代码示例 <script src="https://gw.alipay

  • 问题内容: 大家好,我正尝试通过websockets发送javascript对象: faye-websockets文档说: send(message) 接受字符串或缓冲区,并通过连接向另一对等方发送文本或二进制消息。 服务器端我正在使用node和faye。 客户端: 我的错误是什么?谢谢 问题答案: WebSockets支持发送和接收:字符串,类型数组(ArrayBuffer)和Blob。发送之前

  • 问题内容: 我想知道是否可以在POST请求中直接发送一个数组(未包装在字典中)。显然,该参数应获取以下内容的映射:[String:AnyObject]?但我希望能够发送以下示例json: 问题答案: 您可以使用JSON进行编码,然后自行构建。例如,在Swift 3中:

  • 本文向大家介绍JavaScript 通过POST发送和接收JSON数据,包括了JavaScript 通过POST发送和接收JSON数据的使用技巧和注意事项,需要的朋友参考一下 示例 6 提取请求承诺最初将返回Response对象。它们将提供响应头信息,但它们不直接包含响应主体,而响应主体可能尚未加载。可以使用诸如Response对象上的方法来等待响应主体加载,然后对其进行解析。.json()

  • 我正在开发一个查看器应用程序,其中服务器捕获图像,执行一些图像处理操作,这需要在客户端显示在HTML5画布上。我写的服务器是在VC和使用http://www.codeproject.com/Articles/371188/A-Cplusplus-Websocket-server-for-realtime-interact. 到目前为止,我已经实现了所需的功能。现在我需要做的就是优化。引用是一个用来

  • 在spring文档之后,我能够通过WebSockets通过STOMP发送和接收JSON。然而,在高速率下性能很差,因此我希望分析二进制消息的使用。 Spring腹板套筒4.0 我使用带有必要代理中继的SimpMessageTemplate发送消息-请参阅Spring留档 JavaScript客户端使用stomp接收数据。js使用标准机制。 消息以字符串形式接收,控制台输出如下。我在期待一些原始类型