I have been using socket io for few months now. I had a lot of problem with socket while implementing it in unity. But my main issue is when I receive message/data from socket connection I cannot just call a method to perform some UI related operations. What I came up with to have a boolean variable and do specific operation when the bool is true and perform something inside Update()
which I feel is not the efficient way to do.
Example:
public GameObject IdleGo;
bool isDone = false;
Socket socket;
// Start is called before the first frame update
void Start()
{
InitSocket();
}
// Update is called once per frame
void Update()
{
if(isDone)
{
isDone = false;
IdleGo.SetActive(true);
}
}
void InitSocket()
{
if (socket == null)
{
socket = IO.Socket(ServerURL);
socket.On(Socket.EVENT_CONNECT, () =>
{
Debug.Log("connecting..");
socket.On("response", (data) =>
{
Debug.Log("response: " + data);
if (data == "connected")
{
isDone = true;
}
});
});
}
}
I would love to know how the whole process of socket is done with Unity since I am going to make a multiplayer game as well in near future.
Thanks.
I would move this entire socket thing to a background thread to avoid any blocking.
For awaiting the result in the Unity main thread Update
and a bool
flag is ok but I usually rather use something like
public GameObject IdleGo;
private Socket socket;
// A thread-safe queue for passing a callback into the next Update call
private readonly ConcurrentQueue<Action> _mainThreadhActions = new ConcurrentQueue<Action>();
// Yes! You can make Start return IEnumerator
// In this case Unity automatically starts it as a Coroutine instead
private IEnumerator Start()
{
// Create a new thread in order to run the InitSocketThread method
var thread = new Thread(InitSocketThread);
// start the thread
thread.Start();
// Wait until a callback action is added to the queue
yield return new WaitUntil(() => _mainThreadhActions.Count > 0);
// If this fails something is wrong ^^
// simply get the first added callback
if(!_mainThreadhActions.TryDequeue(out var action))
{
Debug.LogError("Whoops something went wrong!", this);
yield break;
}
// Execute the code of the added callback
action?.Invoke();
}
void InitSocketThread()
{
if (socket == null)
{
socket = IO.Socket(ServerURL);
socket.On(Socket.EVENT_CONNECT, () =>
{
Debug.Log("connecting..");
socket.On("response", (data) =>
{
// Simply wrap your main thread code by wrapping it in a lambda expression
// which is enqueued to the thread-safe queue
_mainThreadhActions.Enqueue(()=>
{
// This will be executed after the next Update call
Debug.Log("response: " + data);
if (data == "connected")
{
IdleGo.SetActive(true);
}
}
});
});
}
}