Помогите с задачей.
Всё пытаюсь сделать чат на Unity
Есть сервер, он работает. Подключает и отключает клиентов.
Консольный чат написал,
WF написал
и всё работает.
Но вот на Unity никак не получается разорвать соединение.
При попытке разорвать сединение, сервер сходит сума. Начинает спамить "пустышками"
Что странно длина сообщения = 28 символам.
А байт 0.
Как видно в момент подключения длина сообщения и байты равны тому что написано
Синтаксис:
Используется csharp
[SerializeField] private InputField Msg_all, Msg_enter;
private string ip = "127.0.0.1";
private int gen_chat_port = 15000;
static string userName;
static TcpClient client;
static NetworkStream stream;
Thread receiveThread = null;
void Start()
{
Connect();
}
private void Disconnect()
{
if (stream != null)
stream.Close();//отключение потока
if (client != null)
client.Close();//отключение клиента
}
private void OnApplicationQuit()
{
#if UNITY_EDITOR
//if (client != null)
//{
// print("client isConnected - " + client.Connected);
// client.Client.Close();
// client.Close();
// print("client isConnected - " + client.Connected);
//}
//Впринципе что и ниже client.Client.Disconnect(true);
client.Client.Disconnect(true);
//Stop playing the scene
EditorApplication.isPlaying = false;
print(EditorApplication.isPlaying);
print("Клиент закрыт спустя " + Time.time + " секунд");
Debug.Log("OnApplicationQuit() Прерывание потока. IsAlive-" + receiveThread.IsAlive);
receiveThread.Abort();
Debug.Log("Abort() IsAlive-" + receiveThread.IsAlive);
// Ожидание прерывания
receiveThread.Join();
Debug.Log("Join() Основной поток прерван. IsAlive-" + receiveThread.IsAlive);
Debug.Log("Клиент закрыт спустя " + Time.time + " секунд");
#endif
}
private void Connect()
{
userName = Environment.UserName;
try
{
userName = Environment.UserName;
client = new TcpClient();
client.Connect(ip, gen_chat_port); //подключение клиента
stream = client.GetStream(); // получаем поток
string message = userName;
byte[] data = Encoding.Unicode.GetBytes(message);
stream.Write(data, 0, data.Length);
// запускаем новый поток для получения данных
receiveThread = new Thread(new ThreadStart(ReceiveMessage));
receiveThread.Start(); //старт потока
print("Добро пожаловать" + userName);//вывод сообщения
SendMessage();
}
catch (Exception ex)
{
print(ex.Message);
}
}
public void SendMessage()
{
string message = Msg_enter.text;
byte[] data = Encoding.Unicode.GetBytes(message);
stream.Write(data, 0, data.Length);
}
private async void ReceiveMessagelAsync()
{
await Task.Run(() => ReceiveMessage());
}
public void ReceiveMessage()
{
while (true)
{
try
{
byte[] data = new byte[64]; // буфер для получаемых данных
StringBuilder builder = new StringBuilder();
int bytes = 0;
do
{
bytes = stream.Read(data, 0, data.Length);
builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
}
while (stream.DataAvailable);
string message = builder.ToString();
if (message != "")
{
print(Environment.NewLine + message);
}
}
catch (Exception ex)
{
print("нет соединения\r\n" + ex.Message);
}
}
}
}
private string ip = "127.0.0.1";
private int gen_chat_port = 15000;
static string userName;
static TcpClient client;
static NetworkStream stream;
Thread receiveThread = null;
void Start()
{
Connect();
}
private void Disconnect()
{
if (stream != null)
stream.Close();//отключение потока
if (client != null)
client.Close();//отключение клиента
}
private void OnApplicationQuit()
{
#if UNITY_EDITOR
//if (client != null)
//{
// print("client isConnected - " + client.Connected);
// client.Client.Close();
// client.Close();
// print("client isConnected - " + client.Connected);
//}
//Впринципе что и ниже client.Client.Disconnect(true);
client.Client.Disconnect(true);
//Stop playing the scene
EditorApplication.isPlaying = false;
print(EditorApplication.isPlaying);
print("Клиент закрыт спустя " + Time.time + " секунд");
Debug.Log("OnApplicationQuit() Прерывание потока. IsAlive-" + receiveThread.IsAlive);
receiveThread.Abort();
Debug.Log("Abort() IsAlive-" + receiveThread.IsAlive);
// Ожидание прерывания
receiveThread.Join();
Debug.Log("Join() Основной поток прерван. IsAlive-" + receiveThread.IsAlive);
Debug.Log("Клиент закрыт спустя " + Time.time + " секунд");
#endif
}
private void Connect()
{
userName = Environment.UserName;
try
{
userName = Environment.UserName;
client = new TcpClient();
client.Connect(ip, gen_chat_port); //подключение клиента
stream = client.GetStream(); // получаем поток
string message = userName;
byte[] data = Encoding.Unicode.GetBytes(message);
stream.Write(data, 0, data.Length);
// запускаем новый поток для получения данных
receiveThread = new Thread(new ThreadStart(ReceiveMessage));
receiveThread.Start(); //старт потока
print("Добро пожаловать" + userName);//вывод сообщения
SendMessage();
}
catch (Exception ex)
{
print(ex.Message);
}
}
public void SendMessage()
{
string message = Msg_enter.text;
byte[] data = Encoding.Unicode.GetBytes(message);
stream.Write(data, 0, data.Length);
}
private async void ReceiveMessagelAsync()
{
await Task.Run(() => ReceiveMessage());
}
public void ReceiveMessage()
{
while (true)
{
try
{
byte[] data = new byte[64]; // буфер для получаемых данных
StringBuilder builder = new StringBuilder();
int bytes = 0;
do
{
bytes = stream.Read(data, 0, data.Length);
builder.Append(Encoding.Unicode.GetString(data, 0, bytes));
}
while (stream.DataAvailable);
string message = builder.ToString();
if (message != "")
{
print(Environment.NewLine + message);
}
}
catch (Exception ex)
{
print("нет соединения\r\n" + ex.Message);
}
}
}
}
Клиент свободно подключается, появляются сообщения. Но вот правильно отключить никак не могу.
Что я делаю не так?
P.S. и ещё. При двух одинаковых сбилденых версиях всё одинаково, только есть одно исключение, если выйти со второго такого клиента, сервер говорит что оба отключились.
А пока второй не вышел, сервер спамит пустышками
P.S.S На WinForms даже Метод Close не делаю, просто закрываю окно и все потоки прекращаются, прекрасно завершая работу