/// ============================================================================================= /// <summary> /// WebSocket接続 /// </summary> /// <param name="serverURL">Ex. ws(wss)://111.222.333.444:8080/disque_clientGameKey</param> /// <param name="token">認証機能を使い場合に使用。</param> /// <param name="param">UDPを使用する際にポート番号を渡す。</param> public void Connect(string ipPort, string gameKey, bool isWss = false, string token = "", string param = "-1") { if (ConnectStatus != eConnectStatus.Disconnected) { Debug.LogError("Already connecting or connected"); return; } ConnectStatus = eConnectStatus.Connecting; var serverURL = string.Format("{0}://{1}/disque_client{2}", (isWss ? "wss" : "ws"), ipPort, gameKey); Debug.Log("[majiXA] connecting to : " + serverURL); WebuSocket = new WebuSocket( serverURL, 1024 * 100, () => { ConnectStatus = eConnectStatus.Connected; }, (Queue <ArraySegment <byte> > datas) => { while (0 < datas.Count) { var data = datas.Dequeue(); var bytes = new byte[data.Count]; Buffer.BlockCopy(data.Array, data.Offset, bytes, 0, data.Count); lock (lockObj) { binaryQueue.Enqueue(bytes); } } }, () => { // pinged. }, (WebuSocketCloseEnum closedReason) => { ConnectStatus = eConnectStatus.Disconnected; reasonCode = (int)closedReason; }, (WebuSocketErrorEnum errorMessage, Exception e) => { ConnectStatus = eConnectStatus.Error; reasonCode = (int)errorMessage; }, new Dictionary <string, string> { { "param", param }, { "token", token } } ); }
// Use this for initialization void Start() { uiScreen = GameObject.Find("EasyTouchControlsCanvas") as GameObject; players = new List <PlayerContext>(); playerModels = new Dictionary <string, GameObject>(); var dateMilliSec = DateTime.Now.Millisecond; UnityEngine.Random.seed = dateMilliSec; playerId = UnityEngine.Random.Range(100, 199).ToString(); Debug.LogError("playerId:" + playerId); var keySetting = (StandardAssetsConnectorSettings)ScriptableObject.CreateInstance("StandardAssetsConnectorSettings"); var WEBSOCKET_ENTRYPOINT = keySetting.DomainKey() + keySetting.ClientKey(); /* * ProcessDataをMainThreadで呼ぶためにセットしている */ Observable.EveryUpdate().Subscribe( _ => { lock (binaryQueue) { if (0 == binaryQueue.Count) { return; } while (0 < binaryQueue.Count) { ProcessData(binaryQueue.Dequeue()); } binaryQueue.Clear(); } } ); webuSocket = new WebuSocket( WEBSOCKET_ENTRYPOINT, 1024 * 100, () => { MainThreadDispatcher.Post( (b) => { Debug.LogError("connected."); XrossPeerLogger.XrossPeer.SetupLogger("client"); //あーー自分で呼び出すの微妙だな、、このコードがどっかに生まれてしまう。どっかに集合を書き出しといて参照したほうが良い気がする。というか // 勝手に書きかわる前提のほうが良いのか。バインド自体はできたんで、そっから考えよう。 // あと実機に入っちゃった場合どうしよう。ifdef書いたら他の環境で詰むなぁ、、、 // ない方が良いケースでどう除外するか、っていうの考え、、たいな、、Editorに居るとかだと自然と守れるんだよな。 // 要件は、 /* * ・XrossPeer内にSetupLoggerがあると、問題が出る(identityを含んだ値がコピーされてしまう) * なので、中にあったら警告とか出さないといけない。 * * ・XrossPeer外にSetupがあるのを推奨したいが。そうとしかできない形を作れればいいんだよな、、、 * うん、Unityなら何とかなるな。っていうかまあ、、いいか、、頑張れって言えば良いや。 */ XrossPeerLogger.XrossPeer.Log("con!!"); }, this ); }, (Queue <ArraySegment <byte> > datas) => { // enqueue datas to local queue. lock (binaryQueue) { while (0 < datas.Count) { var data = datas.Dequeue(); var bytes = new byte[data.Count]; Buffer.BlockCopy(data.Array, data.Offset, bytes, 0, data.Count); binaryQueue.Enqueue(bytes); } } }, () => { Debug.LogError("pingされたぞ〜"); }, closeReason => { Debug.LogError("closeReason:" + closeReason); MainThreadDispatcher.Post( (b) => { // run on main thread. }, this ); }, (errorReason, e) => { Debug.LogError("errorReason:" + errorReason); MainThreadDispatcher.Post( (b) => { // run on main thread. }, this ); }, new Dictionary <string, string> { { "playerId", playerId } } ); }
/// ============================================================================================= /// <summary> /// データ送受信用ループ /// </summary> public void FixedUpdate() { ConnectStatusHandler(); if (ConnectStatus != eConnectStatus.Connected) { return; } // Queueに貯まった送信データを送信 if (sendQueue.Count > 0) { lock (sendLock) { try { foreach (var data in sendQueue) { WebuSocket.Send(data); } sendQueue.Clear(); } catch (Exception e) { Debug.LogError(e.ToString()); } } } // サーバから送信されてきたデータを取得 if (0 < binaryQueue.Count) { lock (lockObj) { try { foreach (var data in binaryQueue) { Receive(data); } binaryQueue.Clear(); } catch (Exception e) { Debug.LogError(e.ToString()); } } } // RTTチェック(数値に変化があった時だけAction着火) timeCount -= Time.deltaTime; if (timeCount < 0f) { WebuSocket.Ping((rtt) => { Rtt = rtt; }); timeCount = 1f; } if (_rtt != Rtt) { rttAct?.Invoke(Rtt); _rtt = Rtt; } }
private void StartReceiving(Action <string> onReceived) { Debug.Log("start receiveing data."); ShowEditorLocalIP(); // WS -> updateへのデータの転送を行うチャンネル。 var chan = Chan <OnUpdatePayload> .Make(); // updateでデータを受け取るブロック。 chan.Receive( (data, ok) => { if (!ok) { return; } onReceived(data.payload); } ); var fp = new FilePersistence(Application.persistentDataPath); ws = new WebuSocket( "ws://" + "127.0.0.1" + ":1129", 10240, () => { // 接続できたipを保存 fp.Update("connectionRecord", "latestIp", "127.0.0.1"); // var data = new byte[1300]; // // for (var i = 0; i < data.Length; i++) // // { // // data[i] = (byte)UnityEngine.Random.Range(0, 100); // // } // try // { // ws.Send(data); // } // catch (Exception e) // { // Debug.Log("ここだ" + e); // } // do nothng. }, segments => { // データを受け取った。受け取りは非メインスレッドなので、メインスレッドに転送する必要がある。 while (0 < segments.Count) { var data = segments.Dequeue(); var bytes = new byte[data.Count]; Buffer.BlockCopy(data.Array, data.Offset, bytes, 0, data.Count); // updateブロックへと転送する var jsonPayload = new OnUpdatePayload(); jsonPayload.payload = Encoding.UTF8.GetString(bytes); chan.Send(jsonPayload); } }, () => { }, closedEnum => { Debug.Log("closedEnum:" + closedEnum); }, (error, reason) => { Debug.Log("error:" + error + " reason:" + reason); }, new Dictionary <string, string> { { "local", "" } } ); }