Unity3d 使用Apache.NMS.ActiveMQ进行通信尝试,主、子线程问题记录
尝试计划
- 尝试计划
- 启动MQ服务
- Unity3D端实现
- 尝试捕获异常
- 解决方案
计划通过一个小程序作为生产者(Producer),并在一定间隔向队列中加入消息,Unity3d端的话作为消费者(Consumer),接收该队列中的消息,并在收到消息后生成一个消息的内容作为名字的节点。
启动MQ服务这一步直接百度实现的,大家自行搜吧。
Unity3D端实现将下载的Apache.NMS.ActiveMQ.dll和Apache.NMS.dll放至工程的Plugins文件夹下,之后就是写代码,新建mq的消费者连接,并绑定监听(Listener):
using Apache.NMS;
using Apache.NMS.ActiveMQ;
using System;
using UnityEngine;
using UnityEngine.UI;
public class MQTest : MonoBehaviour
{
public GameObject go;
void Start()
{
Connect();
}
void Connect()
{
try
{
IConnectionFactory factory = new ConnectionFactory("tcp://127.0.0.1:61616/");
IConnection connection = factory.CreateConnection();
connection.ClientId = "testing listener";
connection.Start();
ISession session = connection.CreateSession();
IMessageConsumer consumer = session.CreateDurableConsumer(new Apache.NMS.ActiveMQ.Commands.ActiveMQTopic("testing"), "testing listener", null, false);
consumer.Listener += new MessageListener(consumer_Listener);
Debug.LogError("服务器连接完成!!!!!!!!");
}
catch (System.Exception e)
{
Debug.LogError(e.Message);
}
}
void consumer_Listener(IMessage message)
{
ITextMessage msg = (ITextMessage)message;
Debug.LogError("接收到MQ数据: " + msg.Text);
GameObject temp = GameObject.Instantiate(go);
temp.name = msg.Text;
}
}
运行起来的效果:
Log显示已经收到数据,但未实例化对象;
尝试捕获异常
void consumer_Listener(IMessage message)
{
try
{
ITextMessage msg = (ITextMessage)message;
Debug.LogError("接收到MQ数据: " + msg.Text);
GameObject temp = GameObject.Instantiate(go);
temp.name = msg.Text;
}
catch (Exception e)
{
Debug.LogError(e.Message);
}
}
找到问题了,不能在子线程里实例化对象。
解决方案先将MQ消息记录在列表,通过FixedUpdate或者Update里面读取处理。
List MsgList = new List();
void Update() {
if (MsgList.Count > 0) {
GameObject temp = GameObject.Instantiate(go);
temp.name = MsgList[0];
Destroy(temp, 3);
MsgList.RemoveAt(0);
}
}
void consumer_Listener(IMessage message)
{
try
{
ITextMessage msg = (ITextMessage)message;
Debug.LogError("接收到MQ数据: " + msg.Text);
MsgList.Add(msg.Text);
}
catch (Exception e)
{
Debug.LogError(e.Message);
}
}