How to use publisher and subscriber codes in a same script in unity3d?

Options
shima
shima Member Posts: 16

Hello ,

I am working with unity and I am trying to use both of the subscriber and publisher in a same unity file so to do that I did following solutions:

  1. I use publisher script and add it to my button and I use subscriber and add it to another Game object but unity crashed Because it wanted to run subscriber and publisher in every frame( that is in update method) with each other so it was impossible for unity.
  2. I made same script for publisher and subscriber like these 2 ways but it didn't work:

(My unity file try to publish the status of button and receive the status of real button from Arduino)

public class PUBSUB : MonoBehaviour

{

  public static string RedStatus;

  [SerializeFeild] private float threshold = 0.1f;

  [SerializeFeild] private float deadzone = 0.025f;

  public bool _isPressedRed;

  public Vector3 _stratPosRed;

  public ConfigurableJoint _jointRed;

  public UnityEvent onPressedRed, onReleasedRed;

  // Start is called before the first frame update

  void Start()

  {

    _stratPosRed = transform.localPosition;

    _jointRed = GetComponent<ConfigurableJoint>();

  }

  // Update is called once per frame

  void Update()

  {

    string host = "localhost";

    string username = "admin";

    string vpnname = "default";

    string password = "admin";

    if (!_isPressedRed && GetValueRed() + threshold >= 1)

      PressedRed();

    if (_isPressedRed && GetValueRed() - threshold <= 0)

      ReleasedRed();

    // 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

        };

        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.");

    Console.ReadLine();

    ContextFactoryProperties cfp1 = new ContextFactoryProperties()

    {

      SolClientLogLevel = SolLogLevel.Warning

    };

    cfp1.LogToConsoleError();

    ContextFactory.Instance.Init(cfp1);

    try

    {

     using (IContext context1 = ContextFactory.Instance.CreateContext(new ContextProperties(), null))

      {

       using (TopicSubscriber topicSubscriber = new TopicSubscriber()

        {

          VPNName = vpnname,

          UserName = username,

          Password = password

        })

        {

          // Run the application within the context and against the host

          topicSubscriber.RunSUB(context1, host);

        }

      }

  }

    catch (Exception ex)

    {

      Console.WriteLine("Exception thrown: {0}", ex.Message);

    }

    finally

    {

       ContextFactory.Instance.Cleanup();

    }

    Console.WriteLine("Finished."); 

  }

  IEnumerator Wait()

  {

    yield return new WaitForSeconds(5);

  }

  public float GetValueRed()

  {

    var value = Vector3.Distance(_stratPosRed, transform.localPosition) / _jointRed.linearLimit.limit;

    if (System.Math.Abs(value) < deadzone)

      value = 0;

    return Mathf.Clamp(value, min: -1f, max: 1f);

  }

  public void PressedRed()

  {

    _isPressedRed = true;

    onPressedRed.Invoke();

    // Re = "Pressed Red Buttom";

    RedStatus = "1";

    Debug.Log(message: RedStatus);

  }

  public void ReleasedRed()

  {

    _isPressedRed = false;

    onReleasedRed.Invoke();

    // Debug.Log(message: "Released Red Buttom");

    RedStatus = "0";

    Debug.Log(message: RedStatus);

  }

 

Comments

  • shima
    shima Member Posts: 16
    Options

     public class TopicPublisher : PUBSUB

      {

        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

          };

           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)

        {

              using (IMessage message = ContextFactory.Instance.CreateMessage())

          {

            message.Destination = ContextFactory.Instance.CreateTopic("tutorial/topic");

             message.BinaryAttachment = Encoding.ASCII.GetBytes(RedStatus);

            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);

            }

          }

        }

      }

      public class TopicSubscriber : PUBSUB, IDisposable

      {

        public string VPNName { get; set; }

        public string UserName { get; set; }

        public string Password { get; set; }

        public const int DefaultReconnectRetries = 3;

        private ISession Session = null;

        private EventWaitHandle WaitEventWaitHandle = new AutoResetEvent(false);

        public void RunSUB(IContext context1, string host)

        {

          // Validate parameters

          if (context1 == null)

          {

            throw new ArgumentException("Solace Systems API context Router must be not null.", "context1");

          }

          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.");

          }

            SessionProperties sessionProps = new SessionProperties()

          {

            Host = host,

            VPNName = VPNName,

            UserName = UserName,

            Password = Password,

            ReconnectRetries = DefaultReconnectRetries

          };

           Console.WriteLine("Connecting as {0}@{1} on {2}...", UserName, VPNName, host);

           Session = context1.CreateSession(sessionProps, HandleMessage, null);

          ReturnCode returnCode = Session.Connect();

          if (returnCode == ReturnCode.SOLCLIENT_OK)

          {

            Console.WriteLine("Session successfully connected.");

            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);

          }

        }

        public void HandleMessage(object source, MessageEventArgs args)

        {

          Console.WriteLine("Received published message.");

          using (IMessage message = args.Message)

          {

             Console.WriteLine("Message content: {0}", Encoding.ASCII.GetString(message.BinaryAttachment));

            String mess = Encoding.ASCII.GetString(message.BinaryAttachment);

            Debug.Log(mess);

           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

      }

    }

  • shima
    shima Member Posts: 16
    Options

    Actually in the above script I ContextFactory.Instance.Init(cfp) for publisher and run it with topicPublisher.Run(context, host) and for subscriber I use ContextFactory.Instance.Init(cfp1)

    and topicSubscriber.RunSUB(context1, host) But it didnt work.

    Also in another attempt I run this code:

    public class PUBSUB : MonoBehaviour

    {

     public static string RedStatus;

     [SerializeFeild] private float threshold = 0.1f;

     [SerializeFeild] private float deadzone = 0.025f;

     public bool _isPressedRed;

     public Vector3 _stratPosRed;

     public ConfigurableJoint _jointRed;

     public UnityEvent onPressedRed, onReleasedRed;

     void Start()

     {

      _stratPosRed = transform.localPosition;

      _jointRed = GetComponent<ConfigurableJoint>();

     }

  • shima
    shima Member Posts: 16
    Options

    void Update()

     {

      string host = "localhost";

      string username = "admin";

      string vpnname = "default";

      string password = "admin";

      if (!_isPressedRed && GetValueRed() + threshold >= 1)

       PressedRed();

      if (_isPressedRed && GetValueRed() - threshold <= 0)

       ReleasedRed();

      ContextFactoryProperties cfp = new ContextFactoryProperties()

      {

       SolClientLogLevel = SolLogLevel.Warning

      };

      cfp.LogToConsoleError();

      ContextFactory.Instance.Init(cfp);

      try

      {

       using (IContext context = ContextFactory.Instance.CreateContext(new ContextProperties(), null))

       {

         TopicPublisher topicPublisher = new TopicPublisher()     

        {

         VPNName = vpnname,

        UserName = username,

         Password = password

        };

        topicPublisher.Run(context, host);

       }

      using (IContext context = ContextFactory.Instance.CreateContext(new ContextProperties(), null))

       {

        TopicSubscriber topicSubscriber = new TopicSubscriber()

        {

         VPNName = vpnname,

         UserName = username,

         Password = password

        };

        topicSubscriber.Run(context, host);

        }

    }

    catch (Exception ex)

      {

       Console.WriteLine("Exception thrown: {0}", ex.Message);

      }

      finally

      {

        ContextFactory.Instance.Cleanup();

      }

      Console.WriteLine("Finished.");

      Console.ReadLine(); ...

    And then I used other methods like previous script actually I run publisher and subscriber with the same cfp and same context But it didnt work.

  • shima
    shima Member Posts: 16
    Options

    I should mention that I can run subscriber and publisher in two different unity file andeach of them individually works and I can publish to solace Broker and receive from it now I need to run them with each other.

    My publisher code is :

    public class RedButton : MonoBehaviour

    {

      public static string Re;

     [SerializeFeild] private float threshold = 0.1f;

     [SerializeFeild] private float deadzone = 0.025f;

     private bool _isPressedRed;

     private Vector3 _stratPosRed;

     private ConfigurableJoint _jointRed;

     public UnityEvent onPressedRed, onReleasedRed;

     void Start()

     {

      _stratPosRed = transform.localPosition;

      _jointRed = GetComponent<ConfigurableJoint>();

     }

     void Update()

     {

       string host = "localhost";

       string username = "admin";

       string vpnname = "default";

       string password = "admin";

       if (!_isPressedRed && GetValueRed() + threshold >= 1)

        PressedRed();

    (_isPressedRed && GetValueRed() - threshold <= 0)

        ReleasedRed();

       ContextFactoryProperties cfp = new ContextFactoryProperties()

       {

        SolClientLogLevel = SolLogLevel.Warning

       };

       cfp.LogToConsoleError();

       ContextFactory.Instance.Init(cfp);

       try

       {

        using (IContext context = ContextFactory.Instance.CreateContext(new ContextProperties(), null))

        {

         TopicPublisher topicPublisher = new TopicPublisher()

         {

          VPNName = vpnname,

          UserName = username,

          Password = password

         };

         topicPublisher.Run(context, host);

        }

       }

       catch (Exception ex)

       {

        Console.WriteLine("Exception thrown: {0}", ex.Message);

       }

       finally

       {

         ContextFactory.Instance.Cleanup();

       }

       Console.WriteLine("Finished.");

       Console.ReadLine();

     }

     IEnumerator Wait()

     {

       yield return new WaitForSeconds(5);

     }

  • shima
    shima Member Posts: 16
    Options

    My publisher and subscriber scripts are made from Solace Github...


    Now ,I should run both of them is a same script in a same unity file, I would apricated it If someone can help me ?