VoxelUnity/Assets/Scripts/NetworkThread.cs

206 lines
4.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using UnityEngine.Assertions;
using UnityEngine;
public class NetworkThread
{
public const int SOCKET_SIZE = 4096;
private Queue<MessageObject> m_received_message_objects;
private Queue<MessageObject> m_outgoing_message_objects;
private object m_handle = new object();
private bool m_end_thread = false;
private System.Threading.Thread m_thread = null;
private TcpClient m_tcp_client = null;
private NetworkStream m_stream = null;
private string m_server_host;
private int m_server_port;
private byte[] m_buffer = new byte[SOCKET_SIZE];
private JSONStreamReader m_json_stream_reader;
public int inbox_count
{
get
{
int c;
lock (m_handle)
{
c = m_received_message_objects.Count;
}
return c;
}
}
public int outbox_count
{
get
{
int c;
lock (m_handle)
{
c = m_outgoing_message_objects.Count;
}
return c;
}
}
public bool end_thread
{
get
{
bool v;
lock(m_handle)
{
v = m_end_thread;
}
return v;
}
set
{
lock(m_handle)
{
m_end_thread = value;
}
}
}
public string server_host
{
get
{
return m_server_host;
}
}
public int server_port
{
get
{
return m_server_port;
}
}
public NetworkThread(string server_host, int server_port)
{
m_server_host = server_host;
m_server_port = server_port;
m_received_message_objects = new Queue<MessageObject>();
m_outgoing_message_objects = new Queue<MessageObject>();
m_json_stream_reader = new JSONStreamReader();
// starting thread
m_thread = new System.Threading.Thread(RunThread);
m_thread.Start();
}
public void SendMessage(MessageObject mo)
{
lock(m_handle)
{
m_outgoing_message_objects.Enqueue(mo);
}
}
public MessageObject PopMessage()
{
MessageObject mo;
lock(m_handle)
{
mo = m_received_message_objects.Dequeue();
}
return mo;
}
private void RunThread()
{
if (!Connect())
{
throw new System.Exception("could not connect to server!");
}
while (! end_thread)
{
while (outbox_count > 0)
{
MessageObject mo;
lock(m_handle)
{
mo = m_outgoing_message_objects.Dequeue();
}
SendMessageObject(mo);
// awaiting answer:
ReceiveReponses();
}
System.Threading.Thread.Sleep(50);
}
Debug.Log("closing network thread");
m_stream.Close();
m_tcp_client.Close();
}
private bool Connect()
{
try
{
m_tcp_client = new TcpClient(m_server_host, m_server_port);
m_stream = m_tcp_client.GetStream();
}
catch (System.Exception e)
{
Debug.Log("Error while establishing network connection");
Debug.Log(e.Message);
return false;
}
Debug.Log("Connected to: " + m_server_host + ":" + m_server_port);
return true;
}
private void SendMessageObject(MessageObject mo)
{
Assert.IsTrue(m_stream != null);
byte[] message = JSONInterpreter.MessageObject2RawJson(mo);
m_stream.Write(message, 0, message.Length);
}
private void ReceiveReponses()
{
Assert.IsTrue(m_stream != null);
while (m_json_stream_reader.is_empty)
{
int n_bytes = m_stream.Read(m_buffer, 0, SOCKET_SIZE);
m_json_stream_reader.AddData(System.Text.Encoding.UTF8.GetString(m_buffer, 0, n_bytes));
}
while (!m_json_stream_reader.is_empty)
{
MessageObject mo = JSONInterpreter.Json2MessageObject(m_json_stream_reader.Pop());
lock(m_handle)
{
m_received_message_objects.Enqueue(mo);
}
}
}
}