private bool TestStateUpdateMessage() { var sup = new StateUpdateObject(); var created = new RoomObjectObj { disposable = true, id = 27, isHidden = false, lookDirection = Vector3.forward, owner = "test", position = Vector3.one, prefab = "a test thing" }; var updated = new RoomObjectObj { disposable = false, id = 23, isHidden = true, lookDirection = Vector3.back, owner = "test", position = Vector3.down, prefab = "" }; var deleted = 0; var TestSUP = new StateUpdateObject { create = new List <RoomObjectObj>() { created }, update = new List <RoomObjectObj>() { updated }, delete = new List <int>() { deleted }, }; var buf = ServerMessageFactory.BuildMessage(TestSUP); var bb = new ByteBuffer(buf); var desMsg = ServerMessage.GetRootAsServerMessage(bb); var passed = true; passed &= desMsg.DataType == msg.StateUpdate; if (passed) { passed &= CompareStateUpdates(desMsg.Data <StateUpdate>().Value, TestSUP); } return(passed); }
public void JoinRoom(string roomName, string userName) { uid = Guid.NewGuid().ToString(); #if UNITY_METRO var devType = "hololens"; #else var devType = "browser"; #endif lastRoomJoined = roomName; socket.SendArray(ServerMessageFactory.BuildMessage(roomName, userName, uid, devType)); print("join request sent"); }
private bool TestStringMessage() { var testString = "TestString"; var buf = ServerMessageFactory.BuildMessage(msgType.SocketCreateOrJoinRoom, testString); var bb = new ByteBuffer(buf); var desMsg = ServerMessage.GetRootAsServerMessage(bb); var passed = true; passed &= desMsg.DataType == msg.StringData; if (passed) { passed &= desMsg.Data <StringData>().Value.Data == testString; } return(passed); }
public IEnumerator Connect(string sid = "") { var w = new WaitForEndOfFrame(); while (isPaused) { yield return(w); } if (connectionState == ConnectionState.Disconnected) { socket = null; connectionState = ConnectionState.Connecting; Debug.Log("Connecting..."); socket = new WebSocket(config.ConnectionEndpoint + ":" + config.Port + "/live" + (!string.IsNullOrEmpty(sid) ? "?sid=" + sid : "")); socket.OnClose += (sender, e) => { print("Closed socket"); connectionState = ConnectionState.Disconnected; if (timeoutCoroutine != null) { StopCoroutine(timeoutCoroutine); } if (e.Reason != "Closed due to user request.") { print("Triggering reconnect"); NeuraManager.Instance.TriggerAutoJoin(); triggerReconnect = StartCoroutine(TriggerReconnect()); } else { sid = ""; } if (OnClose != null) { OnClose.Invoke(sender, e); } }; socket.OnError += (sender, e) => { errorEventArgs.Enqueue(e); }; socket.OnMessage += (sender, e) => { var bb = new ByteBuffer(e.RawData); var desMsg = ServerMessage.GetRootAsServerMessage(bb); // handle heartbeat if (desMsg.Type == msgType.SocketPulse) { lastPulse = Time.realtimeSinceStartup; reconnectAttempts = 0; reconnectTime = 0.1f; socket.SendArray(ServerMessageFactory.BuildMessage()); return; } if (OnMessage != null) { OnMessage.Invoke(sender, e); } }; socket.OnOpen += (sender, e) => { lastPulse = float.MaxValue; timeoutCoroutine = StartCoroutine(TimeoutHandler()); if (triggerReconnect != null) { StopCoroutine(triggerReconnect); } if (OnOpen != null) { OnOpen.Invoke(sender, e); } }; yield return(StartCoroutine(socket.Connect())); #if UNITY_METRO && !UNITY_EDITOR // because messages are received on another thread they need to be processed in a different way than on webgl or in editor StartCoroutine(socket.ProcessMessages()); #endif } }
private bool TestStateUpdateMessage() { var sup = new StateUpdateObject(); var created = new RoomObjectObj { disposable = true, id = 27, isHidden = false, lookDirection = Vector3.forward, owner = "test", position = Vector3.one, prefab = "a test thing" }; var updated = new RoomObjectObj { disposable = false, id = 23, isHidden = true, lookDirection = Vector3.back, owner = "test", position = Vector3.down, prefab = "" }; var deleted = 0; var TestAnnotation = new AnnotationObject { isValid = true, lineId = "testLine", positions = new[] { Vector3.one }, userId = "testUser" }; TargetPlacementObject poi = new TargetPlacementObject { id = 0, isValid = true, name = "testPoi", position = Vector3.one }; var sitedrive = "SomeSiteDrive"; var TestSUP = new StateUpdateObject { poiPlacementObject = poi, annotationObjects = new List <AnnotationObject>() { TestAnnotation }, create = new List <RoomObjectObj>() { created }, update = new List <RoomObjectObj>() { updated }, delete = new List <int>() { deleted }, siteDrive = sitedrive }; var buf = ServerMessageFactory.BuildMessage(TestSUP); var bb = new ByteBuffer(buf); var desMsg = ServerMessage.GetRootAsServerMessage(bb); var passed = true; passed &= desMsg.DataType == msg.StateUpdate; if (passed) { passed &= CompareStateUpdates(desMsg.Data <StateUpdate>().Value, TestSUP); } return(passed); }
private void MessageHandler(object sender, MessageEventArgs e) { var bb = new ByteBuffer(e.RawData); ServerMessage msg = ServerMessage.GetRootAsServerMessage(bb); switch (msg.Type) { case msgType.RoomStateUpdate: //handle message if (msg.Data <StateUpdate>() == null) { print("empty state update. this should not happen"); return; } StateUpdate?stateUpdate = msg.Data <StateUpdate>(); if (stateUpdate != null) { StateUpdate sup = stateUpdate.Value; UpdateLocalState(sup); } break; case msgType.SocketReady: print("connected to server"); StringData?stringData = msg.Data <StringData>(); if (stringData != null) { OnConnectedArgs connectedEventArgs = new OnConnectedArgs { sid = stringData.Value.Data, }; NeuraCore.Instance.sid = connectedEventArgs.sid; } if (OnConnected != null) { OnConnected.Invoke(this, new EventArgs()); } break; case msgType.SocketRoomJoined: { print("Joined room "); inRoom = true; UsersInRoom.Add(localUserName); NeuraCore.Instance.connectionState = ConnectionState.Connected; if (msg.DataType != Transport.FlatBuffers.msg.StateUpdate) { return; } if (msg.Data <StateUpdate>().HasValue) { var initStateSUP = msg.Data <StateUpdate>().Value; UpdateLocalState(initStateSUP); } if (OnRoomJoined != null) { OnRoomJoined.Invoke(this, RoomName); } } break; case msgType.RoomCreated: StringData?createMsg = msg.Data <StringData>(); if (createMsg != null) { //var rmName = createMsg.Value.Data; //RoomName = rmName; print("room " + RoomName + " has been created"); if (OnRoomCreated != null) { OnRoomCreated.Invoke(this, RoomName); } if (string.IsNullOrEmpty((globalState ?? (globalState = new RoomStateGen())).siteDrive)) { //Handle things like critical room state here to make sure that the initial state sent has the required information //For onsight the site drive is of critical importance so we are setting it below //globalState.siteDrive = string.IsNullOrEmpty(requestedSiteDrive) // ? MultiUserConnectionManager.Instance.CurrentSiteDriveJSON // : requestedSiteDrive; } Debug.Assert(!string.IsNullOrEmpty(globalState.siteDrive)); NeuraCore.Instance.SendInitialState(ServerMessageFactory.BuildMessage(globalState)); } break; case msgType.RoomUserOnjoined: StringData?joinedMsg = msg.Data <StringData>(); if (joinedMsg != null) { var user = joinedMsg.Value.Data; print(user + " has joined the room"); UsersInRoom.Add(user); if (OnUserJoined != null) { OnUserJoined.Invoke(this, new UserJoinedEventArgs { username = user }); } } break; case msgType.RoomUserOnLeft: StringData?leftMsg = msg.Data <StringData>(); if (leftMsg != null) { var user = leftMsg.Value.Data; print(user + " has left the room"); if (UsersInRoom.Contains(user)) { UsersInRoom.Remove(user); } if (OnUserLeft != null) { OnUserLeft.Invoke(this, new UserLeftEventArgs { username = user }); } } break; } }
/// <summary> /// Upload any changes in objects owned by the local player, in scene properties, or scene objects /// </summary> private void UploadGlobalState() { lastUpdate = Time.realtimeSinceStartup; if (!inRoom) { return; } List <RoomObjectObj> localObjectsUpdate = new List <RoomObjectObj>(); StateUpdateObject diffState = null; #region Object Updates if (globalState.objects != null) { foreach (RoomObjectObj obj in globalState.objects) { if (!trackers[obj.id].isLocal) { continue; } if (!CompareObjects(obj, trackers[obj.id].ToRoomObject())) { localObjectsUpdate.Add(trackers[obj.id].ToRoomObject()); } } //update the local copy of the global state with the new values for player controlled and scene objects for (int i = 0; i < localObjectsUpdate.Count; i++) { globalState.objects[globalState.objects.IndexOf(localObjectsUpdate[i])] = localObjectsUpdate[i]; } if (localObjectsUpdate.Count != 0 || newRoomObjects.Count != 0) { diffState = new StateUpdateObject { update = localObjectsUpdate }; if (newRoomObjects.Count > 0) { diffState.create = newRoomObjects; } newRoomObjects = new List <RoomObjectObj>(); } } else { print("globalState has no objects"); } #endregion #region Property Updates if (!string.IsNullOrEmpty(requestedSiteDrive)) //update scene { print("site drive changed in global"); var mutState = diffState ?? (diffState = new StateUpdateObject()); mutState.siteDrive = requestedSiteDrive; requestedSiteDrive = ""; oldSiteDrive = ""; } if (requestedPoi.isValid) { print("Setting requested poi"); var mutState = diffState ?? (diffState = new StateUpdateObject()); mutState.PlacePoi(requestedPoi); requestedPoi.isValid = false; } if (requestedAnnotation.isValid) { print("Adding requested annotation"); var mutState = diffState ?? (diffState = new StateUpdateObject()); mutState.AddAnnotation(requestedAnnotation); requestedAnnotation.isValid = false; } if (requestedAnnotationDeletions != null) { var mutState = diffState ?? (diffState = new StateUpdateObject()); for (int i = 0; i < requestedAnnotationDeletions.Count; i++) { var del = requestedAnnotationDeletions[i]; del.positions = new UnityEngine.Vector3[0]; del.isValid = true; mutState.AddAnnotation(del); } requestedAnnotationDeletions = null; } #endregion if (diffState != null ) //Serialize the updates to json and pass them to the NeuraCore to be sent to the server { NeuraCore.Instance.SetUpdate(ServerMessageFactory.BuildMessage(diffState)); } //Find all local owned and scene objects that have changed since the last tick oldStateGen = new RoomStateGen(globalState); }
/// <summary> /// Upload any changes in objects owned by the local player, in scene properties, or scene objects /// </summary> private void UploadGlobalState() { lastUpdate = Time.realtimeSinceStartup; if (!inRoom) { return; } List <RoomObjectObj> localObjectsUpdate = new List <RoomObjectObj>(); StateUpdateObject diffState = null; #region Object Updates if (globalState.objects != null) { foreach (RoomObjectObj obj in globalState.objects) { if (!trackers[obj.id].isLocal) { continue; } if (!CompareObjects(obj, trackers[obj.id].ToRoomObject())) { localObjectsUpdate.Add(trackers[obj.id].ToRoomObject()); } } //update the local copy of the global state with the new values for player controlled and scene objects for (int i = 0; i < localObjectsUpdate.Count; i++) { globalState.objects[globalState.objects.IndexOf(localObjectsUpdate[i])] = localObjectsUpdate[i]; } if (localObjectsUpdate.Count != 0 || newRoomObjects.Count != 0) { diffState = new StateUpdateObject { update = localObjectsUpdate }; if (newRoomObjects.Count > 0) { diffState.create = newRoomObjects; } newRoomObjects = new List <RoomObjectObj>(); } } else { print("globalState has no objects"); } #endregion #region Property Updates #endregion if (diffState != null ) //Serialize the updates to json and pass them to the NeuraCore to be sent to the server { NeuraCore.Instance.SetUpdate(ServerMessageFactory.BuildMessage(diffState)); } //Find all local owned and scene objects that have changed since the last tick oldStateGen = new RoomStateGen(globalState); }