微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

发送AMQP 1.0消息很困难

如何解决发送AMQP 1.0消息很困难

我将Eclipse Hono用作在我的私有Kubernetes集群中本地运行的IoT平台。我已经注册一个通过MQTT接收命令的设备。 在Hono中,必须通过Qpid Network发送命令,该网络使用AMQP 1.0协议发送消息。

我有一个Python代码,用于将msg发送到我的注册设备,该设备已订阅了指定的主题以接收命令(该主题为“ command / + / + / req /#”):

代码如下:

import Tkinter as tkinter
import proton
from cli_proton_python import sender
import ssl
import uuid
import json
from proton._reactor import _generate_uuid
#imports end


# mosquitto_sub -v -h 192.168.1.154 -u rover10@rover -P roversecret -t control/+/+/req/#



#const
scheme = "amqp://"
username = "consumer@HONO"
password = "verysecret"
hostAndPort = "192.168.1.150:15672"
tenant = "rover"
device = "rover1"
topic_to_publish = "command/"+tenant #+"/"+device
speed = 380


def sendControlMsg( msg ):
    print ("sending control msg " + str(msg))
    parser = sender.options.SenderOptions()
    opts,_= parser.parse_args()
        opts.broker_url = scheme + username + ":" + password +"@"+ hostAndPort +"/"+ topic_to_publish
    opts.msg_id = "0" # will be generated automatically
    opts.msg_subject = "RoverDriving"
        opts.msg_content = str(msg)
    opts.msg_reply_to = "command_response/"+tenant+"/"+str(_generate_uuid())
    opts.msg_correlation_id = "null"
    opts.msg_content_type = "application/json"
    opts.log_lib = "TRANSPORT_DRV"
#   opts.log_msgs = 'dict'
    opts.msg_address = "command/"+tenant+"/"+device    

    container = proton.reactor.Container(sender.Send(opts))
    container.run()

#funcs

def turn_right():
    sendControlMsg( "{\"command\":\"E\",\"speed\": "+ str(speed_var.get() + 360) +" }" )
    print("turn right clicked")

def turn_right_back():
    sendControlMsg( "{\"command\":\"D\",\"speed\": "+ str(speed_var.get() + 360) +" }" )
    print("turn right back clicked")

def turn_left():
    sendControlMsg("{\"command\":\"Q\",\"speed\": "+ str(speed_var.get() + 360) +" }")
    print("turn left clicked")

def turn_left_back():
    sendControlMsg("{\"command\":\"A\",\"speed\": "+ str(speed_var.get() + 360) +" }")
    print("turn left back clicked")

def move_forward():
    sendControlMsg("{\"command\":\"W\",\"speed\": "+ str(speed_var.get() + 360) +" }")
    print("move forward clicked")

def move_back():
    sendControlMsg("{\"command\":\"S\",\"speed\": "+ str(speed_var.get() + 360) +" }")
    print("move back clicked")

def spot_right():
    sendControlMsg("{\"command\":\"K\",\"speed\": "+ str(speed_var.get() + 360) +" }")
    print("move spot right clicked")

def spot_left():
    sendControlMsg("{\"command\":\"J\",\"speed\": "+ str(speed_var.get() + 360) +" }")
    print("move spot left clicked")

def stop_move():
    sendControlMsg("{\"command\":\"F\",\"speed\": "+ str(speed_var.get() + 360) +" }")
    print("Stop clicked")

def set_speed(event):
    speed = speed_var.get() + 360
    print("set speed to",speed)
     
def showPosEvent(event):
    print("posevt")
     
def onArrowUp(event):
    move_forward() 
    print("Arrow up")

def onArrowDown(event):
    move_back()
    print("Arrow down")

def onArrowLeft(event):
    turn_left()
    print("Arrow left")

def onArrowRight(event):
    turn_right()
    print("Arrow right")

def onSpaceBar(event):
    stop_move()
    print("Spacebar pressed")


if __name__=="__main__":
    
    tkroot = tkinter.Tk()
    tkroot.title("Rover Controller")
    speed_var = tkinter.DoubleVar() #tkinter.DoubleVar()
    labelfont = ('arial',15,'bold')     

    #Keyboard Input           
    tkroot.bind('<Up>',onArrowUp)
    tkroot.bind('<Down>',onArrowDown)
    tkroot.bind('<Left>',onArrowLeft)
    tkroot.bind('<Right>',onArrowRight)
    tkroot.bind('<space>',onSpaceBar)
    tkroot.focus()
    #Keyboard Input End

    #Buttons
    B_right = tkinter.Button(tkroot,text =">",command= turn_right)
    B_right.place(x = 65,y= 25,height=25,width=25)
   
    B_right_back = tkinter.Button(tkroot,command= turn_right_back)
    B_right_back.place(x = 65,y= 55,width=25)

    B_left  = tkinter.Button(tkroot,text ="<",command= turn_left)
    B_left.place(x= 15,y = 25,width=25)

    B_left_back  = tkinter.Button(tkroot,command= turn_left_back)
    B_left_back.place(x= 15,y = 55,width=25)

    B_up = tkinter.Button(tkroot,text ="^",command= move_forward)
    B_up.place(x= 40,y = 10,width=25)

    B_down = tkinter.Button(tkroot,text ="v",command= move_back)
    B_down.place(x= 40,y = 70,width=25)

    B_stop = tkinter.Button(tkroot,text ="Stop",command= stop_move)
    B_stop.place(x = 10,y = 160,height = 30,width=85)

    B_spot_left = tkinter.Button(tkroot,text ="<)",command= spot_left)
    B_spot_left.place(x = 100,width=35)

    B_spot_right = tkinter.Button(tkroot,text =">(",command= spot_right)
    B_spot_right.place(x = 140,width=35)

    speed_label = tkinter.Label(tkroot,text = "Speed")
    speed_label.place(x= 10,y = 105,height=50,width=50)

    speed_scale = tkinter.Scale(tkroot,variable = speed_var,orient = tkinter.HORIZONTAL)
    speed_scale.bind("<ButtonRelease-1>",set_speed)
    speed_scale.place(x= 60,width=85)
    #Buttons end

    tkroot.mainloop()

当我尝试发送命令时,另一端什么也没有发生,并且它没有传递消息! 然后我试着嗅出数据包,结果发现我的味精中有一个错误,经纪人以“错误的请求”错误作为响应。

Sniffed packets stream

我想知道消息有什么问题吗?是类型还是缺少什​​么!?

解决方法

以下使用Qpid Proton库的Python代码可在Hono Sandbox上使用。

from __future__ import print_function,unicode_literals
from proton import Message
from proton.handlers import MessagingHandler
from proton.reactor import Container

class HelloWorld(MessagingHandler):
    def __init__(self,server,address):
        super(HelloWorld,self).__init__()
        self.server = server
        self.address = address

    def on_start(self,event):
        print("connecting ...")
        conn = event.container.connect(self.server,sasl_enabled=True,allowed_mechs="PLAIN",allow_insecure_mechs=True,user="consumer@HONO",password="verysecret")
        event.container.create_sender(conn,self.address)

    def on_sendable(self,event):
        print("sending command")
        event.sender.send(Message(body="Hello World!",address="command/DEFAULT_TENANT/4711",content_type="text/plain",subject="call"))
        event.sender.close()
        event.connection.close()

Container(HelloWorld("amqp://hono.eclipseprojects.io:15672","command/DEFAULT_TENANT")).run()

我猜您的代码中主要缺少设置SASL属性的信息。我还认为,最好直接设置用户名和密码,而不是将其设置为URL的一部分,因为用户名包含@字符,该字符似乎在URL中也用作分隔符。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。