unity 网络 --NetWorking

unity 5以后底层封装了一些network模块。比较有名的是unet 就是unityNetworkmanager,还是很强大的,用来做一些同步,联机小游戏还是很方便的,因为不需要我们自己再去搭建底层,只需挂载一些组件即可完成过同步。

研究unet的时候,意外发现另一套网络架构--networking。这个相比uent虽然需要我们自己去写更多脚本,但是相比之下,uent性能并不十分稳定,延迟也是比较高的。而networking更类似于我们自己对socket的封装,但是这些底层结构unity已经帮我们搭建,我们可以直接调用。不多说,结合例子开始讲解。

首先作为服务器端,我们可以直接打包,或者在unity上直接 开启服务器,更加直观不想之前只能做Windows窗口程序。

//协议类  数据结构
public class UserMsg : MessageBase
{
    public string SenderIP;
    public string message;
    public string type;
}

public class NetworkingMgr 
{
    private  static NetworkingMgr instance = null;
    public static NetworkingMgr Instance
    {
        get
        {
            if (instance == null)
                instance = new NetworkingMgr();
            return instance;
        }
    }
    public bool connected=false;
    /// <summary>  
    /// 用户信息分类  
    /// </summary>  
    private const short userMsg = 64;
    public string Ip; //服务器IP
    /// <summary>
    /// 获取本机IP
    /// </summary>
    /// <returns></returns>
    private  static string GetInternalIP()
    {
        IPHostEntry host;
        string localIP = "?";
        host = Dns.GetHostEntry(Dns.GetHostName());
        foreach (IPAddress ip in host.AddressList)
        {
            if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
                localIP = ip.ToString();
                break;
            }
        }
        return localIP;
    }
    #region    服务器逻辑
    //玩家连接个数
    public int count = 0;
    private List<NetworkConnection> clients = new List<NetworkConnection>();//记录客户端

    /// <summary>
    /// 启动
    /// </summary>
    /// <param name="ip"></param>
    /// <param name="port"></param>
    public void SeverStart(string ip ,int port)
    {
        if (!NetworkServer.active)
        {
            if (ip == "")
            {
                ip = GetInternalIP();//默认本机做服务器
            }
            if (port == 0)
                port = 4455;
            Ip = GetInternalIP ();
            connected = NetworkServer.Listen(ip, port);
            Debug.Log("服务器启动状态:" + connected);
            if (connected)
                ServerRegisterHandler();
        }
        else
            Debug.Log("服务器已经开启");
    }
    /// <summary>  
    /// 服务器端注册事件  
    /// </summary>  
    private void ServerRegisterHandler()
    {
        NetworkServer.RegisterHandler(MsgType.Connect, OnServerConnected);
        NetworkServer.RegisterHandler(MsgType.Disconnect, OnServerDisconnected);
        NetworkServer.RegisterHandler(MsgType.Error, OnServerError);
        NetworkServer.RegisterHandler(userMsg, ServerGet);//接受消息
    }
    //服务器接受到客户端信息
    private void ServerGet(NetworkMessage netMsg)
    {
        UserMsg Msg = netMsg.ReadMessage<UserMsg>();
        Debug.Log("收到客户端信息:" + Msg.message);
        ServerSendAll(Msg);
        //for (int i = 0; i < clients .Count ; i++)
        //{
        //    SeverSendToClient(Msg, netMsg);
        //}
    }
    //服务器错误事件
    private void OnServerError(NetworkMessage netMsg)
    {
    }
    //有客户端断开事件
    private void OnServerDisconnected(NetworkMessage netMsg)
    {
        count--;
        clients.Remove(netMsg.conn);
        UserMsg msg = new UserMsg()
        {
            message = "掉线!",
            SenderIP = netMsg.conn.address,
            type = "OutLine",
        };
        ServerSendAll(msg);
    }
    // 有客户端登入时调用
    private void OnServerConnected(NetworkMessage msg)
    {
        count++;
        clients.Add(msg.conn);
        Debug.Log("玩家登入:" + msg.conn .address);
    }
    //服务器广播
    public void ServerSendAll(UserMsg um)
    {
        if (NetworkServer.active)
        {
            if (NetworkServer.SendToAll(userMsg, um))
            {
                Debug.Log("Server send:" + um.message);
            }
        }
    }
    //发送给指定客户端
    public void SeverSendToClient(UserMsg um, NetworkMessage netMes)
    {
        if (NetworkServer.active)
        {
            Debug.Log("向客户端发送数据:" + um.message + " ---- " + DateTime.Now);
            NetworkServer.SendToClient(netMes.conn .connectionId  , userMsg, um);
        }
    }
    //停止服务器
    public void ShutdownServer()
    {
        if (NetworkServer.active)
        {
            ServerUnregisterHandler();
            NetworkServer.DisconnectAll();
            NetworkServer.Shutdown();

            if (!NetworkServer.active)
            {
                Debug.Log("shut down server");
            }
        }
    }
    //服务器注销事件
    private void ServerUnregisterHandler()
    {
        NetworkServer.UnregisterHandler(MsgType.Connect);
        NetworkServer.UnregisterHandler(MsgType.Disconnect);
        NetworkServer.UnregisterHandler(MsgType.Error);
        NetworkServer.UnregisterHandler(userMsg);
    }
    #endregion
}

以上只是一个简单是服务器端,当然,如果你想要更可视化,可以自己做些酷炫界面的。

然后是客户端

public class NetworkingMgr 
{
    private  static NetworkingMgr instance = null;
    public static NetworkingMgr Instance
    {
        get
        {
            if (instance == null)
                instance = new NetworkingMgr();
            return instance;
        }
    }
    public bool connected=false;
    /// <summary>  
    /// 用户信息分类  
    /// </summary>  
    private const short userMsg = 64;
  public NetworkClient myClient;//本机客户端
    /// <summary>
    /// 做客户端 连接服务器
    /// </summary>
    /// <param name="ip"></param>
    /// <param name="port"></param>
    public void  Connected(string ip, int port,Action callback)
    {
        if (ip == "")
        {
            ip = GetInternalIP();
        }
        if (port == 0)
            port = 4455;
        myClient = new NetworkClient();
        myClient.Connect(ip, port);
        myClient.RegisterHandler(MsgType.Connect, (netMsg) => 
        {
            Ip = GetInternalIP ();
            connected = myClient.isConnected;
            Debug.Log("连接成功!!!");
            if (callback != null)
                callback.Invoke();
        });
    }
    //向服务器发送信息
    public void ClientSend(UserMsg um)
    {
        if (myClient.isConnected)
        {
            um.SenderIP = Ip;
            if (myClient.Send(userMsg, um))
            {
                Debug.Log("发送成功!!");
            }
        }
    }
    // 客户端注册事件  
    public  void ClientRegisterHandler()
    {
        connected = true;
        //myClient.RegisterHandler(MsgType.Connect, OnClientConnected);
        myClient.RegisterHandler(MsgType.Disconnect, OnClientDisconnected);
        myClient.RegisterHandler(MsgType.Error, OnClientError);
        //myClient.RegisterHandler(userMsg, ClientGet);
    }
    //客户端接受到服务器信息
    //private void ClientGet(NetworkMessage netMsg)
    //{
    //    UserMsg Msg = netMsg.ReadMessage<UserMsg>();
    //    Debug.Log("收到服务器信息:"+Msg.message);
       
    //}
    //客户端错误事件
    private void OnClientError(NetworkMessage netMsg)
    {
    }
    //客户端冲服务器断开事件
    private void OnClientDisconnected(NetworkMessage netMsg)
    {
    }
    //客户端连接到服务器事件
    //private void OnClientConnected(NetworkMessage netMsg)
    //{
    //    connected = myClient.isConnected;
    //    Debug.Log("连接成功!!!");
    //}

    // 停止客户端  
    public void ShutdownClient()
    {
        if (myClient.isConnected)
        {
            ClientUnregisterHandler();
            myClient.Disconnect();

            //NetworkClient.Shutdown()使用后,无法再次连接。  
            //This should be done when a client is no longer going to be used.  
            //myClient.Shutdown ();  
        }
    }
    // 客户端注销事件  
    private void ClientUnregisterHandler()
    {
        myClient.UnregisterHandler(MsgType.Connect);
        myClient.UnregisterHandler(MsgType.Disconnect);
        myClient.UnregisterHandler(MsgType.Error);
        myClient.UnregisterHandler(userMsg);
    }

这些方法接口都是unity封装完成开放的,直接调用就行,启动一个服务器,一个客户端,测试,通过!!


若有问题欢迎咨询指正!!!.


demo下载地址:https://download.csdn.net/download/nt_xs_j/10502072

猜你喜欢

转载自blog.csdn.net/nt_xs_j/article/details/80839015