Hello everyone.

We have decided to phase out the Mixed Reality Forums over the next few months in favor of other ways to connect with us.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

The plan between now and the beginning of May is to clean up old, unanswered questions that are no longer relevant. The forums will remain open and usable.

On May 1st we will be locking the forums to new posts and replies. They will remain available for another three months for the purposes of searching them, and then they will be closed altogether on August 1st.

So, where does that leave our awesome community to ask questions? Well, there are a few places we want to engage with you. For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality. If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers. And always feel free to hit us up on Twitter @MxdRealityDev.

Problems to receive messages from server on HoloLens

Hi guys,

I am developing an app which needs to connect to server in order to receive messages. I am using TCP/IP protocol because I need to establish a previous connection. Becuase of the problem with the System.Net.Sockets library I am using Windows.Networking.Socket library.
The code to use the aforementioned protocol is as follows:

using System;
using System.IO;
using HoloToolkit.Unity;
using UnityEngine;
#if !UNITY_EDITOR
using System.IO;
using System.Threading.Tasks;
using Windows.Networking;
using Windows.Networking.Sockets;
#endif

/// <summary>
/// TcpNetworkClientManager class provides methods to
/// send and receive messages asynchronously
/// </summary>
public class TcpNetworkClientManager : Singleton<TcpNetworkClientManager>
{
    #region PRIVATE_MEMBERS_VARIABLES
    [SerializeField]
    [Tooltip("The Ipv4 address of the machine to connect")]
    private string ip = "127.0.0.1";

    [SerializeField]
    [Tooltip("The connection port on the machine to use")]
    private int port = 9999;

    /// <summary>
    /// The message we receive
    /// </summary>
    private string message;

    /// <summary>
    /// Tracks if a client is connected
    /// </summary>
    private bool clientConnected;

    /// <summary>
    /// Flag to receive message
    /// </summary>
    private bool receiveFlag;

#if !UNITY_EDITOR
    /// <summary>
    /// Supports network communication
    /// </summary>
    StreamSocket socket;

    /// <summary>
    /// Stream of data to write
    /// </summary>
    private StreamWriter writer = null;

    /// <summary>
    /// Stream of data to read
    /// </summary>
    private StreamReader reader = null;
#endif
    #endregion // PRIVATE_MEMBERS_VARIABLES

    #region PUBLIC_MEMBERS_VARIABLES
    public string Ip
    {
        get
        {
            return ip;
        }
        set
        {
            ip = value;
        }
    }

    public int Port
    {
        get
        {
            return port;
        }
        set
        {
            port = value;
        }
    }

    public string Message
    {
        get
        {
            return message;
        }
        set
        {
            message = value;
        }
    }

    public bool ClientConnected
    {
        get
        {
            return clientConnected;
        }
    }
    #endregion // PUBLIC_METHODS

    #region MONOBEHAVIOUR_METHODS
    protected override void Awake()
    {
        base.Awake();
        Message = string.Empty;
        clientConnected = false;
    }
    #endregion // MONOBEHAVIOUR_METHODS

    #region PUBLIC_METHODS
    /// <summary>
    /// Connects to a tcp server using TCP/IP protocol
    /// </summary>
    public void Connect()
    {
        receiveFlag = true;
#if !UNITY_EDITOR
        Task.Run(async () => {
            try
            {
                socket = new StreamSocket();
                await socket.ConnectAsync(new HostName(Ip), Port.ToString());
                clientConnected = true;
                writer = new StreamWriter(socket.OutputStream.AsStreamForWrite());
                reader = new StreamReader(socket.InputStream.AsStreamForRead());
                await Receive();
            }
            catch(Exception)
            {
                Debug.Log("Unable to connecto to server");
            }
        });
#endif
        Debug.LogWarningFormat("Tcp connect not supported in editor");
    }

    /// <summary>
    /// Sends asynchronously a message using TCP/IP protocol
    /// </summary>
    /// <param name="data"></param>
    public void Send(string messageToSend)
    {
#if !UNITY_EDITOR
        if (writer != null) Task.Run(async () =>
        {
            try
            {
                await writer.WriteAsync(messageToSend);
                await writer.FlushAsync();
                Debug.Log("Sent: " + messageToSend);
            }
            catch(Exception)
            {
                Debug.Log("Unable to send message to server");
            }
        });
#endif
        Debug.LogWarningFormat("Tcp send not supported in editor");
    }

    /// <summary>
    /// Frees resources both reader and writer
    /// </summary>
    public void Close()
    {
#if !UNITY_EDITOR
        receiveFlag = false;

        if (writer != null) writer.Dispose();
        writer = null;

        if (reader != null) reader.Dispose();
        reader = null;
#endif
        Debug.LogWarningFormat("Tcp close not supported in editor");
    }
    #endregion // PUBLIC_METHODS

    #region PRIVATE_METHODS
    /// <summary>
    /// Receives asynchronously a message using TCP/IP protocol
    /// </summary>
#if !UNITY_EDITOR
    private async Task Receive()
    {
        if (reader != null)
        {
            while (receiveFlag)
            {
                try
                {
                    if (clientConnected)
                    {
                        string messageToReceive = await reader.ReadToEndAsync();
                        if (messageToReceive != null)
                        {
                            Message = messageToReceive;
                            Debug.Log("Received: " + message);
                        }
                    }
                }
                catch (Exception)
                {
                    Debug.Log("Unable to receive from server");
                }
            }
        }
    }
#endif
    #endregion // PRIVATE_METHODS
}

Although I can connect to the server, I do not receive anything. I know that the Receive() function reaches to

string messageToReceive = await reader.ReadToEndAsync();

but the next statements are not called, that is, the thread is waiting for data, but the data never is received.

Does anyone know what trouble I am having?

Thanks in advance,
Cristian.

Best Answer

  • Accepted Answer

    I found the solution after trying different approaches. The code that solved the problem is as follows:

    char[] buffer = new char[bufferSize];
    int bytes = await reader.ReadAsync(buffer, 0, buffer.Length);
    
        if (bytes > 0)
        {
            string result = new string(buffer, 0, bytes);
            message = result;
    
            Debug.Log("Received: " + message);
        }
    

    The problem was ReadToEndAsync, since with a stream socket there should be no "end of stream" delimiter.

    I hope this approach can help someone,
    Cristian.

Answers

  • Accepted Answer

    I found the solution after trying different approaches. The code that solved the problem is as follows:

    char[] buffer = new char[bufferSize];
    int bytes = await reader.ReadAsync(buffer, 0, buffer.Length);
    
        if (bytes > 0)
        {
            string result = new string(buffer, 0, bytes);
            message = result;
    
            Debug.Log("Received: " + message);
        }
    

    The problem was ReadToEndAsync, since with a stream socket there should be no "end of stream" delimiter.

    I hope this approach can help someone,
    Cristian.

Sign In or Register to comment.