用unity开发hololens应用的传输数据的注意事项

来源:互联网 发布:u盘怎么恢复数据 编辑:程序博客网 时间:2024/05/01 01:26

最近学校引进了一台hololens,本人非常开心,老师让我做数据传输的方面,本以为会非常简单,以为只是用c#的.net类就可以了。没想到做完之后bulild为windows应用时各种报错,找遍了各种文档最后才发现unity对windows应用的支持还是有欠缺的,例如.net的部分类用不了,www类也不能用。这对于想用unity做带有网络数据传输的windows应用开发特别不利,想了很多办法,最后决定用unity引擎自带的unet来做。值得注意的是unet有hlapi于llapi,这两个一个是底层的一个是上层的,llapi可以定制的比较多所以我选择了llapi。用上之后才发现是如此之坑,我按照unity官方文档来做的但是可以连接但不可以传数据,这个问题困扰了我两天,最后在unity的问题反馈那找到了答案,因为llapi是用的transport layer api用的是udp所以不是面向连接,服务端、客户端连上端口后,客户端会连接服务端,然后建立了连接。注意,此时发不了数据,客户端必须知道连上之后才能发,而且每次只能发一次。也就是说只能连一次发一次,真的是巨坑,如果想少数次的发少量数据可以用它,多次发数据就别用它了。以下是代码
服务端
int socketId;
int connectionId;
int myUnreliableChannelId;
int myReiliableChannelId;

// Use this for initializationvoid Start(){    NetworkTransport.Init();    ConnectionConfig config = new ConnectionConfig();    myReiliableChannelId = config.AddChannel(QosType.Reliable);  //    myUnreliableChannelId = config.AddChannel(QosType.Unreliable);    HostTopology topology = new HostTopology(config, 10);    socketId = NetworkTransport.AddHost(topology, 8888);    byte error;    connectionId = NetworkTransport.Connect(socketId, "192.168.0.100", 2000, 0, out error);    }    // Update is called once per framevoid Update(){    int recHostId;    int connectionId1;    int channelId;    byte[] recBuffer = new byte[1024];    int bufferSize = 1024;    int dataSize;    byte error;    NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId1, out channelId, recBuffer, bufferSize, out dataSize, out error);    switch (recData)    {        case NetworkEventType.Nothing:            Debug.Log("nothing");            break;        case NetworkEventType.ConnectEvent:            byte[] buffer;            buffer = System.Text.Encoding.Default.GetBytes("123");            byte error1;            NetworkTransport.Send(socketId, connectionId, myReiliableChannelId, buffer, bufferSize, out error1);            Debug.Log((NetworkError)error1);            Debug.Log(System.Text.Encoding.Default.GetString(buffer));            break;        case NetworkEventType.DataEvent:            string message = System.Text.Encoding.Unicode.GetString(recBuffer);            Debug.Log("incoming message event received: " + message);            break;        case NetworkEventType.DisconnectEvent:            Debug.Log("remote client event disconnected");            break;    }    客户端:    建立什么的跟服务端差不多,就是多个connect

public void Connect() {
byte error;
connectionId = NetworkTransport.Connect(socketId, “localhost”, socketPort, 0, out error);
Debug.Log(“Connected to server. ConnectionId: ” + connectionId);
}
注意客户端发数据之前一定要判断dataevent:
public void SendSocketMessage() {
byte error;
byte[] buffer = new byte[1024];
Stream stream = new MemoryStream(buffer);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, “HelloServer”);

int bufferSize = 1024;
NetworkEventType recData = NetworkTransport.Receive(out recHostId, out connectionId1, out channelId, recBuffer, bufferSize, out dataSize, out error);
switch (recData)
{
case NetworkEventType.Nothing:
Debug.Log(“nothing”);
break;
case NetworkEventType.ConnectEvent:
byte[] buffer;
buffer = System.Text.Encoding.Default.GetBytes(“123”);
byte error1;
NetworkTransport.Send(socketId, connectionId, myReiliableChannelId, buffer, bufferSize, out error1);
Debug.Log((NetworkError)error1);
Debug.Log(System.Text.Encoding.Default.GetString(buffer));
break;
case NetworkEventType.DataEvent:
string message = System.Text.Encoding.Unicode.GetString(recBuffer);
Debug.Log(“incoming message event received: ” + message);
break;
case NetworkEventType.DisconnectEvent:
Debug.Log(“remote client event disconnected”);
break;
}
不要复制我的代码,我代码有很多错误只是告诉一下中心思想,记住send之前一定要receive以下判断是否已连接,只有连接上才能发数据,而且只能发一次。还有就是unity做windows应用时system.io也用不了。

由于llapi不好用,所以我建议大家用hlapi来传数据,很好用的。以下是代码

“`
这里写代码片
客户端:

NetworkClient myClient;
int i = 0;
// Use this for initialization
void Start () {
myClient = new NetworkClient();
myClient.RegisterHandler(MsgType.Connect, OnConnected);
myClient.RegisterHandler(MsgType.Disconnect, OnDisconnected);
myClient.RegisterHandler(MsgType.Error, OnError);
ConnectionConfig Config = new ConnectionConfig();
Config.AddChannel(QosType.Reliable);
Config.AddChannel(QosType.Unreliable);
Config.AddChannel(QosType.ReliableFragmented);
HostTopology Topology = new HostTopology(Config, 10);
myClient.Configure(Topology);
myClient.Connect(“169.254.4.251”, 7070);
}

private void OnError(NetworkMessage netMsg){    throw new NotImplementedException();}private void OnDisconnected(NetworkMessage netMsg){    throw new NotImplementedException();}private void OnConnected(NetworkMessage netMsg){    Debug.Log("connect");        RegisterHostMessage message = new RegisterHostMessage();        message.gameName = ""+i;        myClient.Send(1002, message);    InvokeRepeating("sendtoserver", 0.3f, 0.3f);    } private void sendtoserver(){    RegisterHostMessage message = new RegisterHostMessage();    message.gameName = "" + i;    myClient.Send(1002, message);    i++;    Debug.Log(i);

“`}
class RegisterHostMessage : MessageBase
{
public string gameName;

}

服务端:
const short MyBeginMsg = 1002;
public Text text;

void Start(){    ConnectionConfig Config = new ConnectionConfig();    NetworkServer.RegisterHandler(MsgType.Connect, OnConnected);    NetworkServer.RegisterHandler(MyBeginMsg, OnServerReadyToBeginMessage);    Config.AddChannel(QosType.Reliable);    Config.AddChannel(QosType.Unreliable);    Config.AddChannel(QosType.ReliableFragmented);    HostTopology Topology = new HostTopology(Config, 10);    NetworkServer.Configure(Topology);    NetworkServer.Listen(7070);}private void OnServerReadyToBeginMessage(NetworkMessage netMsg){    var beginMessage = netMsg.ReadMessage<RegisterHostMessage>();

// Debug.Log(“received OnServerReadyToBeginMessage ” + beginMessage.gameName);
text.text = beginMessage.gameName;
}

void OnConnected(NetworkMessage netMsg){    Debug.Log("Client connected");}// Update is called once per framevoid Update(){}

}
class RegisterHostMessage : MessageBase
{
public string gameName;

}
以上就是unity开发windows应用的网络传输的方法

0 0