我开始认为自己在VB.net上表现得很好,但是没有这个让我感到难过。
代码看起来像这样
Public Class MyServer
.....
Public myMQTTclient = New MqttClient("www.myserv.com")
.....
Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles
MyBase.Load
<some code>
StartMQTT()
<some more code>
MQTT_Publish(.....)
End Sub
Public Function StartMQTT()
' Establish a connection
Dim code As Byte
Try
code = myMQTTclient.Connect(MQTT_ClientID)
Catch ex As Exception
<error handling code>
End Try
Return code
End Function
Public Sub MQTT_Publish(ByVal DeviceID As String, ByVal Channel As String, ByVal ChannelType As String, ByVal Value As String, ByVal Unit As String)
Dim myTopic As String = "MyTopic"
Dim myPayload As String = "My Payload"
Dim msgId As UShort = myMQTTclient.Publish(myTopic, Encoding.UTF8.GetBytes(myPayload), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, False)
End Sub
现在它可以100%正常工作。编码可能看起来有点奇怪,但意图如下:
a)在模块级别创建一个对象'myMQTTclient',使其在整个模块中具有范围
b)运行StartMQTT() - 它仍然可以看到对象。
c)在主程序调用MQTT_Publish中多次 - 我仍然可以看到对象
现在的问题是这个......一切顺利,直到“www.myserv.com”失败DNS,然后底层的winsock代码抛出异常。
所以...我在想 - 没问题 - 只需将声明包装在try块中,或在启动声明之前检查www.myserv.com是否存在。
啊,但你不能把代码放在模块级别,它必须在子或函数中。
嗯......现在我很难过。必须有一个“正确”的方法来做到这一点,但如果我能弄清楚的话,我会被愚弄。任何人都可以提供帮助吗?
答案 0 :(得分:0)
好的,我不确定我是否拥有合适的库。但是我找到了这个Nuget包:OpenNETCF.MQTT,它似乎有你正在使用的类。
我会这样做
Public Class MyServerClass
Implements IDisposable
Public myMQTTclient As MQTTClient
'Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles MyBase.Load
' ' <some code>
' StartMQTT()
' ' <some more code>
' ' MQTT_Publish(.....)
'End Sub
Public Sub New(brokerHostName As String)
myMQTTclient = New MQTTClient(brokerHostName)
End Sub
Public Function StartMQTT()
' Establish a connection
Dim code As Byte
Try
code = myMQTTclient.Connect(MQTT_ClientID)
Catch ex As Exception
'<error handling code>
End Try
Return code
End Function
Public Sub MQTT_Publish(ByVal DeviceID As String, ByVal Channel As String, ByVal ChannelType As String, ByVal Value As String, ByVal Unit As String)
Dim myTopic As String = "MyTopic"
Dim myPayload As String = "My Payload"
Dim msgId As UShort = myMQTTclient.Publish(myTopic, Encoding.UTF8.GetBytes(myPayload), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, False)
End Sub
#Region "IDisposable Support"
Private disposedValue As Boolean
Protected Overridable Sub Dispose(disposing As Boolean)
If Not disposedValue Then
If disposing Then
myMQTTclient.Dispose()
End If
End If
disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
End Sub
#End Region
End Class
现在,您可以在Using
块中看到实施IDisposable时的用法:
Module Module1
Sub Main()
Using myserver As New MyServerClass("www.myserv.com")
myserver.StartMQTT()
myserver.MQTT_Publish(...)
End Using
End Sub
End Module
这使得你的对象只在Using中的范围内,并且对象的Dispose方法将自动在End Using
上调用
我不知道基类最初是什么以及为什么声明Private Sub Ruptela_Server(sender As Object, e As EventArgs) Handles MyBase.Load
。好像它可能是一种形式?如果是这种情况,您应该将服务器代码与表单代码分开。我想你可以将Using
粘贴到表单加载中,但是你会阻止你的UI线程。引用的库具有Async支持,因此如果来自UI,可能最好利用它。
我做了很多假设,所以我会停下来让你发表评论,看看我的答案有多接近。