Search code examples
c#unity-game-enginetcptcpclient

call a code when done playing in unity


I got a tcp server in JAVA and a class called Client among the unity scripts. Client is a singleton that connects to the server at its constructor. When I press the play button it connects to the server but when I press again to stop the game the client is not disconnects automatically so when I run the game again it gets stack because he tries to connect from a computer he already connected. I tried to disconnect at the destructor but it never been called. how can I do it? I also tried to implement IDisposable but I do not know if you need to call it or the garbage collector calls it (for me it is not). this is the client's code (read write and loop are not important for the question but I left it in case someone wants it):

using Assets.Scripts.Tools;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;
using System;

public class Client : System.Object, IDisposable{
    private TcpClient tcp;
    private Stream stream;
    private IClientCallback callback;
    private Thread recvThread;

    private static Client instance = null;

    public static Client Instance
    {
        get
        {
            if (instance == null)
                instance = new Client();
            return instance;
        }
    }

    private Client()
    {
        Init();
    }

    public void Init()
    {
        Log.D("Init the client");
        tcp = new TcpClient();
        tcp.Connect(Main.IP, Main.PORT);
        stream = tcp.GetStream();
        recvThread = new Thread(loop);
        recvThread.Start();
    }

    public void setCallback(IClientCallback callback)
    {
        this.callback = callback;
    }

    // recving loop
    private void loop()
    {
        while (true)
        {
            Message msg = Read();
            if (callback != null)
            {
                callback.Callback(msg);
            }
            else
            {
                Log.E("callbackPointer is null, msg not handheld");
            }
        }
    }

    public void disconnect()
    {
        tcp.Close();
        stream.Close();
    }

    // read a message from the server (will wait until a message is recved
    private Message Read()
    {
        try
        {
            int val;
            string res = "";
            do
            {
                val = stream.ReadByte();
                res += (char)val;
            } while (val != Code.END_MESSAGE && val != -1);
            return new Message(res);
        }
        catch (IOException)
        {
            Log.E("Could not read from the server, disconnecting");
            throw new System.Exception("could not read from the server");
        }
    }

    // Write a message to the server
    public void Write(Message msg)
    {
        try
        {
            Log.D("Write:", msg.getDebug());
            stream.Write(msg.getBytes(), 0, msg.getBytes().Length);
            stream.Flush();
        }
        catch (IOException)
        {
            Log.E("Could not send message to the client");
            throw new System.Exception("could not write to the server: " + msg.getCode().ToString() + msg.toString());
        }
    }

    public void Dispose()
    {
        Log.D("never been called");
    }

    ~Client()
    {
        Log.D("never been called");
    }
}

Solution

  • Use the OnApplicationQuit() callback function and disconnect from your tcp server or call your disconnect() method within there. This callback will run right before the application closes, both in the editor and in a built standalone player.
    OnApplicationQuit()