unity插件之进程间通信TcpSocket

由于项目需要,需要研究unity插件的进程间通信

进程间通信的方式很多,不过由于unity的限制以及实际需求考虑采用TcpSocket  的方式

首先线程启动链接,会多次重连,防止掉线

    public void Connect()
    {
        if (m_autoConnectThread != null)
        {
            log("已经运行");
            return;
        }
        try
        {
            m_autoConnectThread = new Thread(new ThreadStart(autoConnectThreadRun));
            m_autoConnectThread.Start();
        }
        catch
        {
            log("启动线程错误...");
        }
    }
    private void autoConnectThreadRun()
    {
        while (true)
        {
            if ((m_socketSend == null) || !m_socketSend.Connected)
            {
                log("自动连接中...");
                doConnect();
                System.Threading.Thread.Sleep(2000);
            }
            else
            {
                long heartBeatTime = LYZXCommon.DateTimeToUnixMSLong(DateTime.Now);
                // 大于4秒就Ping 1次
                if (heartBeatTime - m_heartBeatTime > 4)
                {
                    Send("ping");
                    System.Threading.Thread.Sleep(1000);
                }
                else
                {
                    System.Threading.Thread.Sleep(3000);
                }
            }
        }
    }

异步连接服务器:

    private void doConnect()
    {
        m_socketSend = new TcpClient();
        log("准备连接服务器");
        m_socketSend.BeginConnect(c_ip, c_port, connectAsync, null);
    }
    void connectAsync(IAsyncResult result)
    {
        if (m_socketSend.Connected)
        {
            m_heartBeatTime = LYZXCommon.DateTimeToUnixMSLong(DateTime.Now);
            log("连接服务器成功 -> " + m_socketSend.Client.RemoteEndPoint);
            //开启异步读取消息
            m_buffer = new byte[c_buffseSize];
            m_stream = m_socketSend.GetStream();
            m_stream.BeginRead(m_buffer, 0, m_buffer.Length, readAsync, null);
        }
        else
        {
            log("连接服务器失败");
        }
    }

异步读取消息,先读取消息,记录心跳时间,然后开始下一次异步读取:

    void readAsync(IAsyncResult result)
    {
        if ((m_stream == null) || (m_socketSend == null) || (!m_socketSend.Connected))
        {
            return;
        }
        try
        {
            int readCount = m_stream.EndRead(result);
            if (readCount == 0)
            {
                Send("ping");
            }
            else
            {
                string msg = Encoding.UTF8.GetString(m_buffer, 0, readCount);
                log("接收到消息 -> " + msg);
                m_heartBeatTime = LYZXCommon.DateTimeToUnixMSLong(DateTime.Now);
            }
            lock (m_stream) //再次开启读取
            {
                Array.Clear(m_buffer, 0, m_buffer.Length);
                m_stream.BeginRead(m_buffer, 0, m_buffer.Length, readAsync, null);
            }
        }
        catch(Exception e)
        {
            Debug.Log("ee:" + e.Message);
        }
    }

发送消息:

    public void Send(string str)
    {
        if (m_stream != null)
        {
            try
            {
                string msg = str;
                byte[] buffer = new byte[1024 * 1024 * 3];
                buffer = Encoding.UTF8.GetBytes(msg);
                m_stream.Write(buffer, 0, buffer.Length);
                log("发送消息 -> " + msg);
                m_heartBeatTime = LYZXCommon.DateTimeToUnixMSLong(DateTime.Now);
            }
            catch (Exception e)
            {
                log(e.Message);
            }
        }
    }

好了,有了异步通信,我们就可以写我们的业务代码了

整体代码如下


public class TcpSocketTest2
{
    private const string c_ip = "127.0.0.1";
    private const int c_port = 33333;
    private const int c_buffseSize = 8192;

    TcpClient m_socketSend;
    NetworkStream m_stream;
    byte[] m_buffer;
    private Thread m_autoConnectThread;
    private long m_heartBeatTime;
    private bool m_showLog = true;
    
    private void log(string msg)
    {
        if (m_showLog)
        {
            UnityEngine.Debug.Log(msg);
        }
    }

    public void Init()
    {
        m_heartBeatTime = 0;
    }

    public void Connect()
    {
        if (m_autoConnectThread != null)
        {
            log("已经运行");
            return;
        }
        try
        {
            m_autoConnectThread = new Thread(new ThreadStart(autoConnectThreadRun));
            m_autoConnectThread.Start();
        }
        catch
        {
            log("启动线程错误...");
        }
    }

    private void autoConnectThreadRun()
    {
        while (true)
        {
            if ((m_socketSend == null) || !m_socketSend.Connected)
            {
                log("自动连接中...");
                doConnect();
                System.Threading.Thread.Sleep(2000);
            }
            else
            {
                long heartBeatTime = LYZXCommon.DateTimeToUnixMSLong(DateTime.Now);
                // 大于4秒就Ping 1次
                if (heartBeatTime - m_heartBeatTime > 4)
                {
                    Send("ping");
                    System.Threading.Thread.Sleep(1000);
                }
                else
                {
                    System.Threading.Thread.Sleep(3000);
                }
            }
        }
    }

    private void doConnect()
    {
        m_socketSend = new TcpClient();
        log("准备连接服务器");
        m_socketSend.BeginConnect(c_ip, c_port, connectAsync, null);
    }

    void connectAsync(IAsyncResult result)
    {
        if (m_socketSend.Connected)
        {
            m_heartBeatTime = LYZXCommon.DateTimeToUnixMSLong(DateTime.Now);
            log("连接服务器成功 -> " + m_socketSend.Client.RemoteEndPoint);
            //开启异步读取消息
            m_buffer = new byte[c_buffseSize];
            m_stream = m_socketSend.GetStream();
            m_stream.BeginRead(m_buffer, 0, m_buffer.Length, readAsync, null);
        }
        else
        {
            log("连接服务器失败");
        }
    }

    public void Terminated()
    {
        if (m_autoConnectThread != null)
        {
            m_autoConnectThread.Abort();
            m_autoConnectThread = null;
        }

        if (m_stream != null)
        {
            m_stream.Close();
            m_stream = null;
        }
        if (m_socketSend != null)
        {
            m_socketSend.Close();
            m_socketSend = null;
        }
    }

    void readAsync(IAsyncResult result)
    {
        if ((m_stream == null) || (m_socketSend == null) || (!m_socketSend.Connected))
        {
            return;
        }
        try
        {
            int readCount = m_stream.EndRead(result);
            if (readCount == 0)
            {
                Send("ping");
            }
            else
            {
                string msg = Encoding.UTF8.GetString(m_buffer, 0, readCount);
                log("接收到消息 -> " + msg);
                m_heartBeatTime = LYZXCommon.DateTimeToUnixMSLong(DateTime.Now);
            }
            lock (m_stream) //再次开启读取
            {
                Array.Clear(m_buffer, 0, m_buffer.Length);
                m_stream.BeginRead(m_buffer, 0, m_buffer.Length, readAsync, null);
            }
        }
        catch(Exception e)
        {
            Debug.Log("ee:" + e.Message);
        }
    }

    public void Send(string str)
    {
        if (m_stream != null)
        {
            try
            {
                string msg = str;
                byte[] buffer = new byte[1024 * 1024 * 3];
                buffer = Encoding.UTF8.GetBytes(msg);
                m_stream.Write(buffer, 0, buffer.Length);
                log("发送消息 -> " + msg);
                m_heartBeatTime = LYZXCommon.DateTimeToUnixMSLong(DateTime.Now);
            }
            catch (Exception e)
            {
                log(e.Message);
            }
        }
    }
}

 

 

你可能感兴趣的:(Unity3d,unity3d,网络通信,c#,udp)