How to integrate unity3d and Solace pubsub?
Hi I am very happy that I can join to your community.
Since some months ago I was working with solace pub sub+ and now I want to integrate Solace to unity3d for publishing messages from unity to Solace I didn't have any problem but to receive data from Solace and using unity as a subscriber I had lots of problem and I couldn't do that.
I would be apricated it if you could help me or connecting me to someone that works with unity and Solace.
Answers
-
I want to receive messages from Solace and show it in the unity console. Using
https://docs.solace.com/Solace-PubSub-Messaging-APIs/dotNet-API/net-api-home.htm https://github.com/SolaceSamples/solace-samples-dotnet https://tutorials.solace.dev/dotnet/publish-subscribe/First I added dll files to unity. Then I make this script and added it to camera.
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Text; using SolaceSystems.Solclient.Messaging; using System.Threading; using UnityEngine.UI; public class Newsub : MonoBehaviour { #region start void start() { Debug.Log("1"); string host = "localhost"; string username = "admin"; string vpnname = "default"; string password = "admin"; // Initialize Solace Systems Messaging API with logging to console at Warning level ContextFactoryProperties cfp = new ContextFactoryProperties() { SolClientLogLevel = SolLogLevel.Warning }; cfp.LogToConsoleError(); ContextFactory.Instance.Init(cfp); try { // Context must be created first using (IContext context = ContextFactory.Instance.CreateContext(new ContextProperties(), null)) { // Create the application using (TopicSubscriber topicSubscriber = new TopicSubscriber() { VPNName = vpnname, UserName = username, Password = password }) { // Run the application within the context and against the host topicSubscriber.Run(context, host); } } } catch (Exception ex) { Console.WriteLine("Exception thrown: {0}", ex.Message); } finally { // Dispose Solace Systems Messaging API ContextFactory.Instance.Cleanup(); } Console.WriteLine("Finished."); Console.WriteLine("message"); Debug.Log("message"); } #endregion /// <summary> /// Demonstrates how to use Solace Systems Messaging API for subscribing to a topic and receiving a message /// </summary> public class TopicSubscriber : IDisposable { public string VPNName { get; set; } public string UserName { get; set; } public string Password { get; set; } public const int DefaultReconnectRetries = 3; public ISession Session = null; public EventWaitHandle WaitEventWaitHandle = new AutoResetEvent(false); public void Run(IContext context, string host) { // Validate parameters if (context == null) { throw new ArgumentException("Solace Systems API context Router must be not null.", "context"); } if (string.IsNullOrWhiteSpace(host)) { throw new ArgumentException("Solace Messaging Router host name must be non-empty.", "host"); } if (string.IsNullOrWhiteSpace(VPNName)) { throw new InvalidOperationException("VPN name must be non-empty."); } if (string.IsNullOrWhiteSpace(UserName)) { throw new InvalidOperationException("Client username must be non-empty."); } // Create session properties SessionProperties sessionProps = new SessionProperties() { Host = host, VPNName = VPNName, UserName = UserName, Password = Password, ReconnectRetries = DefaultReconnectRetries }; // Connect to the Solace messaging router Console.WriteLine("Connecting as {0}@{1} on {2}...", UserName, VPNName, host); // NOTICE HandleMessage as the message event handler Session = context.CreateSession(sessionProps, HandleMessage, null); ReturnCode returnCode = Session.Connect(); if (returnCode == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected."); // This is the topic on Solace messaging router where a message is published // Must subscribe to it to receive messages Session.Subscribe(ContextFactory.Instance.CreateTopic("tutorial/topic"), true); Console.WriteLine("Waiting for a message to be published..."); WaitEventWaitHandle.WaitOne(); } else { Console.WriteLine("Error connecting, return code: {0}", returnCode); } } /// <summary> /// This event handler is invoked by Solace Systems Messaging API when a message arrives /// </summary> /// <param name="source"></param> /// <param name="args"></param> public void HandleMessage(object source, MessageEventArgs args) { Console.WriteLine("Received published message."); // Received a message using (IMessage message = args.Message) { // Expecting the message content as a binary attachment Console.WriteLine("Message content: {0}", Encoding.ASCII.GetString(message.BinaryAttachment)); // finish the program WaitEventWaitHandle.Set(); } } #region IDisposable Support private bool disposedValue = false; protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { if (Session != null) { Session.Dispose(); } } disposedValue = true; } } public void Dispose() { Dispose(true); } #endregion /*#region start void start() { string host = "localhost"; string username = "admin"; string vpnname = "default"; string password = "admin"; // Initialize Solace Systems Messaging API with logging to console at Warning level ContextFactoryProperties cfp = new ContextFactoryProperties() { SolClientLogLevel = SolLogLevel.Warning }; cfp.LogToConsoleError(); ContextFactory.Instance.Init(cfp); try { // Context must be created first using (IContext context = ContextFactory.Instance.CreateContext(new ContextProperties(), null)) { // Create the application using (TopicSubscriber topicSubscriber = new TopicSubscriber() { VPNName = vpnname, UserName = username, Password = password }) { // Run the application within the context and against the host topicSubscriber.Run(context, host); } } } catch (Exception ex) { Console.WriteLine("Exception thrown: {0}", ex.Message); } finally { // Dispose Solace Systems Messaging API ContextFactory.Instance.Cleanup(); } Console.WriteLine("Finished."); Console.WriteLine("message"); Debug.Log("message"); } #endregion*/ } }
Actually I want to run Topicsubscriber from this link in unity
https://github.com/SolaceSamples/solace-samples-dotnet.I would be appreciate it if you can help me and if you want I can send my unity file.
0 -
Hey Tamimi, actually first I run your code as a subscriber in visual studio and it works but when I use this code and run it in unity I couldn't receive anything from my Solace publisher. It doesn't show anything in console.
I used your Topic publisher code and I could to send message from unity to solace( here Solace was my subscribrer) but I don't know where is the problem in unity that I couldn't receive messages in it.In advance thanks for your help.
0 -
Thanks for the details on this Shima. Some important things to look for is
1. Your connection parameters and
2. Topics you are publishing/subscribing toSince your TopicPublisher sample application was able to connect to the Solace Broker, this leaves us with potentially a mismatch topic subscription. It looks like your TopicSubscriber is attempting to subscribe to topic
tutorial/topic
. How are you testing the subscription process? I am assuming you are running the TopicSubscriber application on unity, and from your Solace Broker management console TryMe tab you are publishing ontutorial/topic
correct? Please confirm the setup.The TopicSubscriber samples has a couple of console writes so are you able to see some logs in the console confirming successful connection to the Solace Broker
Console.WriteLine("Session successfully connected.");
?0 -
Thanks for your information Tamimi.
Actually our team was working with Solace from some months ago also in some questions our team got some helps from you.
As I mentioned I could run your Topicsubscriber code in vs with this topic and this connection parameters with the Solace Broker management console TryMe tab and it works , I think my problem is related to unity if someone works with unity and solace maybe can help me more but I didn't find anyone in unity community that works with Solace.
In vs I got good results from the GitHub c# samples but in unity in console I didn't receive any log even I put " Debug.Log("1");" in the start function in the fist line but it doesn't print it in the console if you want I can send my unity file completely.0 -
Hmm interesting. and you mentioned that you did not change any of the TopicSubscriber or TopicPublisher code correct? I'll keep an eye opened to see if there are any particular unity related caveats you have to take into account.
If you made changes to the files from the samples found on the github repo can you mention what changes you made?
0 -
Potentially as well another thing you can confirm on your broker managment console, you can check the connected clients. Run your subscriber in unity and confirm if the client is detected on the broker as a client connection. If you cant find it this means that the connection was not successful
0 -
So thanks for your support.
Specifically I want to know that which part of this code is related to start function in unity and which part is related to another options in unity?
In terms of the clients I checked that even when I don't have any subscriber it shows one subscriber and when I run unity it doesn't add another subscriber now I don't understand when I don't have any subscriber why it shows one as default subscriber?To run topicpublisher I changed the code like below, this code will send the position of my object to Solace broker.
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Text; using SolaceSystems.Solclient.Messaging; public class NewBehaviourScript : MonoBehaviour { public float speed; public static string position; public void Update() { float horizontal = Input.GetAxis("Horizontal") * Time.deltaTime * speed; transform.Translate(horizontal, 0, 0); Vector3 pos = transform.position; position = pos.ToString(); Debug.Log(position); string host = "localhost"; // Solace messaging router host name or IP address string username = "admin"; string vpnname = "default"; string password = "admin"; // Initialize Solace Systems Messaging API with logging to console at Warning level ContextFactoryProperties cfp = new ContextFactoryProperties() { SolClientLogLevel = SolLogLevel.Warning }; cfp.LogToConsoleError(); ContextFactory.Instance.Init(cfp); try { // Context must be created first using (IContext context = ContextFactory.Instance.CreateContext(new ContextProperties(), null)) { // Create the application TopicPublisher topicPublisher = new TopicPublisher() { VPNName = vpnname, UserName = username, Password = password }; // Run the application within the context and against the host topicPublisher.Run(context, host); } } catch (Exception ex) { Console.WriteLine("Exception thrown: {0}", ex.Message); } finally { // Dispose Solace Systems Messaging API ContextFactory.Instance.Cleanup(); } Console.WriteLine("Finished."); } public class TopicPublisher : NewBehaviourScript { public string VPNName { get; set; } public string UserName { get; set; } public string Password { get; set; } public const int DefaultReconnectRetries = 3; public void Run(IContext context, string host) { // Validate parameters if (context == null) { throw new ArgumentException("Solace Systems API context Router must be not null.", "context"); } if (string.IsNullOrWhiteSpace(host)) { throw new ArgumentException("Solace Messaging Router host name must be non-empty.", "host"); } if (string.IsNullOrWhiteSpace(VPNName)) { throw new InvalidOperationException("VPN name must be non-empty."); } if (string.IsNullOrWhiteSpace(UserName)) { throw new InvalidOperationException("Client username must be non-empty."); } // Create session properties SessionProperties sessionProps = new SessionProperties() { Host = host, VPNName = VPNName, UserName = UserName, Password = Password, ReconnectRetries = DefaultReconnectRetries }; // Connect to the Solace messaging router Console.WriteLine("Connecting as {0}@{1} on {2}...", UserName, VPNName, host); using (ISession session = context.CreateSession(sessionProps, null, null)) { ReturnCode returnCode = session.Connect(); if (returnCode == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected."); PublishMessage(session); } else { Console.WriteLine("Error connecting, return code: {0}", returnCode); } } } public void PublishMessage(ISession session) { //position = NewBehaviourScript.position; // Create the message using (IMessage message = ContextFactory.Instance.CreateMessage()) { message.Destination = ContextFactory.Instance.CreateTopic("tutorial/topic"); // Create the message content as a binary attachment message.BinaryAttachment = Encoding.ASCII.GetBytes(position); // Publish the message to the topic on the Solace messaging router Console.WriteLine("Publishing message..."); ReturnCode returnCode = session.Send(message); if (returnCode == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Done."); } else { Console.WriteLine("Publishing failed, return code: {0}", returnCode); } } } } // Start is called before the first frame update void Start() { speed = 10f; } }
0 -
So thats a start, if you dont see a client connection on your broker being added when you start your subscriber on unity, then the issue is with connection.
Do you have your code on a github repo we can take a look at it? Maybe your TopicSubscriber code is not reaching
session.Connect()
. Try adding some console logs in the following code blocks to better understand the behaviour of your topicSubscriberConsole.WriteLine("Connecting as {0}@{1} on {2}...", UserName, VPNName, host); // NOTICE HandleMessage as the message event handler Session = context.CreateSession(sessionProps, HandleMessage, null); ReturnCode returnCode = Session.Connect(); if (returnCode == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected."); // This is the topic on Solace messaging router where a message is published // Must subscribe to it to receive messages Session.Subscribe(ContextFactory.Instance.CreateTopic("tutorial/topic"), true); Console.WriteLine("Waiting for a message to be published..."); WaitEventWaitHandle.WaitOne(); } else { Console.WriteLine("Error connecting, return code: {0}", returnCode); }
I got this from here https://github.com/SolaceSamples/solace-samples-dotnet/blob/master/src/TopicSubscriber/TopicSubscriber.cs#L77-L96.
Regarding this question you had:
In terms of the clients I checked that even when I don't have any subscriber it shows one subscriber and when I run unity it doesn't add another subscriber now I don't understand when I don't have any subscriber why it shows one as default subscriber?
is it a
#client-username
client? It might be either a default client or one of your TryMe connections. It might be difficult to tell without having any further information on what youre seeingAnd btw, I modified your last comment to include ``` before and after your codeblock for better code formatting in comments
1