Unity2D:UNET传输层API服务器脚本没有正确的消息传递

时间:2017-04-18 19:35:50

标签: unity3d unity3d-unet

我在YouTube上关注tutorial团结多人游戏(UNET),但与视频中的人相比,我获得了不同的结果。你看我跟着他的教程去了茶,但是在更新功能的服务器脚本中,我在switch语句默认函数中使用了debug.log,告诉我是否收到了无效的消息,我就是这样。我认为我的信息并没有被正确发送,尽管我仔细地按照了这个人的教程!我在服务器脚本中遗漏了什么吗?

这是我的代码:

public class ServerClient
 {
  public int connectionId;
  public string playerName;
 }

public class Server : MonoBehaviour {

private const int MAX_CONNECTION = 4;

private int port = 8888;

private int hostId;
private int webHostId;

private int reliableChannel;
private int unreliableChannel;

private bool isStarted = false;
private byte error;

private List<ServerClient> clients = new List<ServerClient>();

private void Start()
{
    NetworkTransport.Init ();
    ConnectionConfig cc = new ConnectionConfig ();

    reliableChannel = cc.AddChannel (QosType.Reliable);
    unreliableChannel = cc.AddChannel (QosType.Unreliable);

    HostTopology topo = new HostTopology (cc, MAX_CONNECTION);

    hostId = NetworkTransport.AddHost (topo, port); // null
    Debug.Log ("Socket Open. hostId is: " + hostId);
    webHostId = NetworkTransport.AddWebsocketHost (topo, port, null); //, port, null

    isStarted = true;
}

private void Update()
{
    if (!isStarted)
        return;

    int recHostId;
    int connectionId;
    int channelId;
    byte[] recBuffer = new byte[1024];
    int bufferSize = 1024;
    int dataSize;
    byte error;
    NetworkEventType recData = NetworkTransport.Receive (out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
    switch (recData) {
    case NetworkEventType.ConnectEvent:   //2
        Debug.Log ("Player " + connectionId + "has connected");
        OnConnection (connectionId);
        break;
    case NetworkEventType.DataEvent:      //3
        string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
        //Debug.Log("Player" + connectionId + " has sent :  " + msg);
        Debug.Log("Recieving from " + connectionId + " : " + msg);

        string[] splitData = msg.Split ('|');

        switch (splitData[0])
        {
        case "OnNameIs":
            OnNameIs (connectionId, splitData [1]);
                break;

            default:
                Debug.Log ("Invalid message:  " + msg);
                break;
        }

        break;

        case NetworkEventType.DisconnectEvent:     // 4
        Debug.Log("Player " + connectionId + "has disconnected");
        break;
    }
}


private void OnConnection(int cnnId)
{
    // This may add a thrid player 
     ServerClient c = new ServerClient();
     c.connectionId = cnnId;
     c.playerName = "TEMP";
     clients.Add(c);
     //So you might want to change this later 

    string msg = "AskName|" + cnnId + "|";
    foreach (ServerClient sc in clients) 
        msg += sc.playerName + '%' + sc.connectionId + '|';

    msg = msg.Trim ('|');

    Send (msg, reliableChannel, cnnId); 
}

private void OnNameIs(int cnnId, string playerName)
{
    clients.Find (x => x.connectionId == cnnId).playerName = playerName;

    Send ("CNN|" + playerName + '|' + cnnId, reliableChannel, clients);
}

private void Send(string message, int channelId, int cnnId)
{
    List<ServerClient> c = new List<ServerClient>();
    c.Add (clients.Find (x => x.connectionId == cnnId));
    Send (message, channelId, c);
}

private void Send(string message, int channelId, List<ServerClient> c)
{
    Debug.Log ("Sending  : " + message);
    byte[] msg = Encoding.Unicode.GetBytes (message);
    foreach (ServerClient sc in c) 
    {
        NetworkTransport.Send (hostId, sc.connectionId, channelId, msg, message.Length * sizeof(char), out error);
    }
}

}

以下脚本是我的客户端脚本:

public class Player
{
  public string playerName;
  public GameObject avatar;
  public int connectionId;
}

public class Client : MonoBehaviour {


private const int MAX_CONNECTION = 4;

private int port = 8888; //5701

private int hostId;
private int webHostId;

private int connectionId;
private int ourClientId;

private int reliableChannel;
private int unreliableChannel;

private float connectionTime;
private bool isConnected = false;
private bool isStarted = false;
private byte error;

private string playerName;

public GameObject playerPrefab;

public List<Player> players = new List<Player>();

public void Connect()
{
    //Does the player have a name?
    //take this part out
    string pName = GameObject.Find("NameInput").GetComponent<InputField>().text;

    if (pName == "") {
        Debug.Log ("you must enter a name");
        return;
    }

    playerName = pName;

    //

    // place this is the Start fuction
    NetworkTransport.Init ();
    ConnectionConfig cc = new ConnectionConfig ();

    reliableChannel = cc.AddChannel (QosType.Reliable);
    unreliableChannel = cc.AddChannel (QosType.Unreliable);

    HostTopology topo = new HostTopology (cc, MAX_CONNECTION);

    hostId = NetworkTransport.AddHost (topo, 0);
    //

    byte error;
    connectionId = NetworkTransport.Connect (hostId, "127.0.0.1", port, 0, out error);
    Debug.Log ("Connection to server. ConnectionId: " + connectionId);
    connectionTime = Time.time;
    isConnected = true;
}

private void Update()
{
    if (!isConnected)
        return;

    int recHostId;
    int connectionId;
    int channelId;
    byte[] recBuffer = new byte[1024];
    int bufferSize = 1024;
    int dataSize;
    byte error;
    NetworkEventType recData = NetworkTransport.Receive (out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);
    switch (recData) {
    case NetworkEventType.DataEvent:      //1
        string msg = Encoding.Unicode.GetString (recBuffer, 0, dataSize);
        Debug.Log ("Recieving : " + msg);
        string[] splitData = msg.Split ('|');

        switch (splitData[0])
        {
        case "AskName":
            OnAskName (splitData);
            break;

        case "CNN":
            SpawnPlayer (splitData[1], int.Parse(splitData[2]));
            break;

        case "DC":
            break;

        default:
            Debug.Log ("Invalid message:  " + msg);
            break;
        }

        break;
    }
}

private void OnAskName(string[] data)
{ 
    ourClientId = int.Parse (data [1]);

    Send ("OnNameis|" + playerName, reliableChannel);

    for (int i = 2; i < data.Length - 1; i++)
    {
        string[] d = data[i].Split('%');
        SpawnPlayer(d[0], int.Parse(d[1]));
    }
}

private void SpawnPlayer(string playerName, int cnnId)
{
    GameObject go = Instantiate (playerPrefab) as GameObject;
    Debug.Log ("Object has been spawn", go);

    if (cnnId == ourClientId)  // the problem //
    {
        GameObject.Find("Canvas").SetActive (false);
        isStarted = true;
    }

    Player p = new Player ();
    p.avatar = go;
    p.playerName = playerName;
    p.connectionId = cnnId;
    p.avatar.GetComponentInChildren<TextMesh>().text = playerName;
    players.Add (p);
}

private void Send(string message, int channelId)
{
    Debug.Log ("Sending  : " + message);
    byte[] msg = Encoding.Unicode.GetBytes (message);
    NetworkTransport.Send (hostId, connectionId, channelId, msg, message.Length * sizeof(char), out error);
}

提前谢谢!

1 个答案:

答案 0 :(得分:1)

不太对茶。 仔细观察,你会看到:

  • 客户端发送名为OnNameis
  • 的命令
  • 服务器需要名为OnNameIs
  • 的命令

这几乎说明了使用字符串命令的危险。改为使用枚举。