前言
用于记录我在学习MQTT中 所遇到的问题,在这里做一个记录,防止以后忘记了。
Unity报错部分
MqttCommunicationException: Error in the application.
MqttCommunicationException: Error in the application. uPLibrary.Networking.M2Mqtt.MqttClient.SendReceive (System.Byte[] msgBytes, System.Int32 timeout) (at Assets/MQTT/scripts/MqttClient.cs:953). 上面的报错翻译过来是:连接超时,引发的原因有:
- Unity程序中的账号或者密码错误
- Unity输入IP或者端口号输入错误
- MQTT服务器端没有为tcp连接设置连接的IP和端口号
由于目标计算机积极拒绝
这个是由于网络的原因(猜测,我也不知道):
- 检查UnityIP检查端口号
- 检查服务器端的IP和端口号是否正确
- 检查服务器端的控制台是否是开启,如果把开启服务器的控台关闭也会提示这个,使用Web客户端会提示:连接异常断开:AMQJS0008I Socket closed.
ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: port 翻译过来说:端口号超过最大的长度 端口号的最大长度是:65535(2的16次方)
ArgumentOutOfRangeException: Number must be either non-negative and less than or equal to Int32. MaxValue or -1.
翻译过来说是:参数超出范围异常:Number必须是非负且小于或等于Int32。 最大值或-1。 看不懂,暂时没有解决
UnityException: get_isActiveAndEnabled can only be called from the main thread.
UnityException: get_isActiveAndEnabled can only be called from the main thread. Constructors and field initializers will be executed from the loading thread when loading a scene. Don’t use this function iUnityException: get_isActiveAndEnabled只能从主线程调用。 翻译过来是:当加载场景时,构造函数和字段初始化器将在加载线程中执行。 不要在构造函数或字段初始化器中使用这个函数,而是将初始化代码移动到Awake或Start函数中。 n the constructor or field initializers, instead move initialization code to the Awake or Start function.
解决办法:有的地方在子线程中修改了Unity的gameObject,将对gameobject的操作放到主线中进行,例如将对物体的操作放到timer的方法中。
提供部分代码,限于apollo使用。
Apollo的服务器端口的配置文件
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version
2.0 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless required by
applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and
limitations under the License.
-->
<!--
For more information on how configure this file please
reference:
http://activemq.apache.org/apollo/versions/1.7.1/website/documentation/user-manual.html
-->
<broker xmlns="http://activemq.apache.org/schema/activemq/apollo">
<notes>
The default configuration with tls/ssl enabled.
</notes>
<log_category console="console" security="security" connection="connection" audit="audit"/>
<authentication domain="apollo"/>
<!-- Give admins full access -->
<access_rule allow="admins" action="*"/>
<access_rule allow="*" action="connect" kind="connector"/>
<virtual_host id="myapollo">
<!--
You should add all the host names that this virtual host is known as
to properly support the STOMP 1.1 virtual host feature.
-->
<host_name>myapollo</host_name>
<host_name>localhost</host_name>
<host_name>127.0.0.1</host_name>
<!-- Uncomment to disable security for the virtual host -->
<!-- <authentication enabled="false"/> -->
<!-- Uncomment to disable security for the virtual host -->
<!-- <authentication enabled="false"/> -->
<access_rule allow="users" action="connect create destroy send receive consume"/>
<!-- You can delete this element if you want to disable persistence for this virtual host -->
<leveldb_store directory="${apollo.base}/data"/>
</virtual_host>
<web_admin bind="http://127.0.0.1:61680"/><!-- 服务器的IP和端口号-->
<web_admin bind="https://127.0.0.1:61681"/>
<connector id="tcp" bind="tcp://127.0.0.1:61613" connection_limit="2000"/><!-- 客户端的IP和端口号 -->
<connector id="tls" bind="tls://127.0.0.1:61614" connection_limit="2000"/>
<connector id="ws" bind="ws://127.0.0.1:61623" connection_limit="2000"/>
<connector id="wss" bind="wss://127.0.0.1:61624" connection_limit="2000"/>
<key_storage file="${apollo.base}/etc/keystore" password="password" key_password="password"/>
</broker>
使用
https://127.0.0.1:61681
http://127.0.0.1:6168
来访问服务器的网站,网站的账号(admin)密码(password),在客户端使用根据使用的协议访问不同的网站以及IP,参照下面的代码,如果更改需要重新启动客户端。
<connector id="tcp" bind="tcp://127.0.0.1:61613" connection_limit="2000"/><!-- Unity客户端,以及使用tcp协议的客户端所需要连接的IP以及端口号 -->
<connector id="tls" bind="tls://127.0.0.1:61614" connection_limit="2000"/>
<connector id="ws" bind="ws://127.0.0.1:61623" connection_limit="2000"/><!-- web客户端 -->
<connector id="wss" bind="wss://127.0.0.1:61624" connection_limit="2000"/>
Unity客户端连接部分
如果是拷贝的上面的配置文件 则连接部分为
private void btnConnect_Click()
{
//IP127.0.0.1 PORT 61613
string txtIP = inputIP.text;
string txtPort = inputPort.text;
string clientId = Guid.NewGuid().ToString();
string username = "admin";
string password = "password";
client = new MqttClient(IPAddress.Parse(txtIP), int.Parse(txtPort), false, null);
client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
client.MqttMsgSubscribed += Client_MqttMsgSubscribed;
client.Connect(clientId, username, password);
Debug.Log("开始连接");
}
并未进行更改,增加了IP和端口号的注释,用于以后的记录。
|