Unity2017で非同期処理が使えない
HoloLens(クライアント側)でwebsocket通信を利用しようとしています。
他クライアントからサーバーへの接続を確認できたためHoloLens実機で接続テストしようとしたのですが、以下の部分の処理途中でアプリケーションが止まってしまっています。
private void OnConnect() {
AppendOutputLine("OnConnect");
messageWebSocket = new MessageWebSocket();
messageWebSocket.Control.MessageType = SocketMessageType.Utf8;
messageWebSocket.MessageReceived += WebSock_MessageReceived;
messageWebSocket.Closed += WebSock_Closed;
Uri serverUri = new Uri("ws://192.168.11.2:1880");
try {
Task.Run(async () => {
//Connect to the server.
AppendOutputLine("Connect to the server..." + serverUri.ToString());
await Task.Run(async () => {
AppendOutputLine("Task Run :" + serverUri.ToString());
await messageWebSocket.ConnectAsync(serverUri);
AppendOutputLine("ConnectAsync OK");
await WebSock_SendMessage(messageWebSocket, "Connect Start");
});
//AppendOutputLine("miss await Task");
});
}
catch (Exception ex) {
AppendOutputLine("error : " + ex.ToString());
//Add code here to handle any exceptions
}
具体的には、"Connect to the server... ws://192.168.11.2:1880"が表示された段階でアプリケーションが止まり、その後の await Task.Run(async () => {});
が実行できていません。
Unityの
Scripting Runtime Version を Experimental(.NET 4.6 Equivalent)に、
Api Compatibility Level を .NET 4.6 に
変更したのですが、状況は変わりませんでした。
もし分かる方がいらっしゃいましたら、解決方法を教えて頂きたいです。
環境
Unity2017.4.17f1
VisualStudio2017
Hololens OSbuild:10.0.17763.316
ソースコードはこの記事を参考にしています。
以下、ソースコード全文
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
using UnityEngine.UI;
#if UNITY_EDITOR
using WebSocketSharp; // Unity
using WebSocketSharp.Net;
#else
using System.Threading.Tasks;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
#endif
public class WebSocketController : MonoBehaviour {
#if UNITY_EDITOR
WebSocket ws;
#else
private MessageWebSocket messageWebSocket;
private DataWriter messageWriter;
private bool busy;
#endif
private Text targetText;
// Use this for initialization
void Start () {
this.targetText = this.GetComponent<Text>();
this.targetText.text = "Start";
#if UNITY_EDITOR
this.targetText.text = "Unity_Editor";
ws = new WebSocket("ws://192.168.11.2:1880");
var context = SynchronizationContext.Current;
ws.OnOpen += (sender, e) =>
{
Debug.Log("WebSocket Open");
};
ws.OnMessage += (sender, e) =>
{
Debug.Log("WebSocket Receive message: " + e.Data);
// Main threadで実行
context.Post(state => {
this.targetText.text = state.ToString();
}, e.Data);
};
ws.OnError += (sender, e) =>
{
Debug.Log("WebSocket Error Message: " + e.Message);
};
ws.OnClose += (sender, e) =>
{
Debug.Log("WebSocket Close");
};
ws.Connect();
#else
// HoloLens実機でWebSocket接続開始
this.targetText.text = "Unity_UWP";
OnConnect();
#endif
}
// Update is called once per frame
void Update () {
#if UNITY_EDITOR
//if (Input.GetKeyUp("s")) {
// ws.Send("Test Message");
//}
#else
#endif
}
#if UNITY_EDITOR
void OnDestroy() {
ws.Close();
ws = null;
}
#else
private void OnConnect() {
AppendOutputLine("OnConnect");
messageWebSocket = new MessageWebSocket();
//In this case we will be sending/receiving a string so we need to set the MessageType to Utf8.
messageWebSocket.Control.MessageType = SocketMessageType.Utf8;
//Add the MessageReceived event handler.
messageWebSocket.MessageReceived += WebSock_MessageReceived;
//Add the Closed event handler.
messageWebSocket.Closed += WebSock_Closed;
// Uri serverUri = new Uri("ws://192.168.11.2:1880/testws"); // 別PCのNode-REDのWebSocketにつながる
Uri serverUri = new Uri("ws://192.168.11.2:1880");
try {
Task.Run(async () => {
//Connect to the server.
AppendOutputLine("Connect to the server..." + serverUri.ToString());
await Task.Run(async () => {
AppendOutputLine("Task Run :" + serverUri.ToString());
await messageWebSocket.ConnectAsync(serverUri);
AppendOutputLine("ConnectAsync OK");
await WebSock_SendMessage(messageWebSocket, "Connect Start");
});
//AppendOutputLine("miss await Task");
});
}
catch (Exception ex) {
AppendOutputLine("error : " + ex.ToString());
//Add code here to handle any exceptions
}
}
private async Task WebSock_SendMessage(MessageWebSocket webSock, string message) {
AppendOutputLine("WebSock_SendMessage : " + message);
DataWriter messageWriter = new DataWriter(webSock.OutputStream);
messageWriter.WriteString(message);
await messageWriter.StoreAsync();
}
private void WebSock_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args) {
DataReader messageReader = args.GetDataReader();
messageReader.UnicodeEncoding = UnicodeEncoding.Utf8;
string messageString = messageReader.ReadString(messageReader.UnconsumedBufferLength);
AppendOutputLine("messageString : " + messageString);
//Add code here to do something with the string that is received.
Task.Run(async () => {
UnityEngine.WSA.Application.InvokeOnAppThread(() => {
AppendOutputLine("InvokeOnAppThread : iTween");
this.targetText.text = messageString;
}, true);
await Task.Delay(100);
});
}
private void WebSock_Closed(IWebSocket sender, WebSocketClosedEventArgs args)
{
//Add code here to do something when the connection is closed locally or by the server
}
private void AppendOutputLine(string value)
{
// OutputField.Text += value + "\r\n";
//Debug.Log(value);
this.targetText.text = value;
}
#endif
}