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);
        }
Example #2
0
        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");
        }
Example #3
0
        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);
        }
Example #4
0
        private static void Test2()
        {
            var facS = new ServerMessageFactory(true);

            var bytes = new byte[10000];

            new Random().NextBytes(bytes);

            var msg = facS.CreateNew <VesselSrvMsg>(new VesselProtoMsgData
            {
                VesselId   = Guid.NewGuid(),
                VesselData = bytes,
                SentTime   = DateTime.UtcNow.Ticks
            });

            //Serialize and compress
            var serialized = msg.Serialize(true);

            serialized = msg.Serialize(true);
            serialized = msg.Serialize(true);
            serialized = msg.Serialize(true);

            //Serialize no compress
            var serializedNc = msg.Serialize(false);

            serializedNc = msg.Serialize(false);
            serializedNc = msg.Serialize(false);
            serializedNc = msg.Serialize(false);

            var msg2 = facS.Deserialize(serialized, Environment.TickCount);

            msg2 = facS.Deserialize(serialized, Environment.TickCount);
            msg2 = facS.Deserialize(serialized, Environment.TickCount);
            msg2 = facS.Deserialize(serialized, Environment.TickCount);

            var msg2Nc = facS.Deserialize(serializedNc, Environment.TickCount);

            msg2Nc = facS.Deserialize(serializedNc, Environment.TickCount);
            msg2Nc = facS.Deserialize(serializedNc, Environment.TickCount);
            msg2Nc = facS.Deserialize(serializedNc, Environment.TickCount);

            var ok = ((VesselProtoMsgData)msg.Data).VesselData.SequenceEqual(((VesselProtoMsgData)msg2.Data).VesselData) &&
                     ((VesselProtoMsgData)msg2Nc.Data).VesselData.SequenceEqual(((VesselProtoMsgData)msg2.Data).VesselData);
        }
        public static ServerMessage ReadMessage(byte[] buffer, int length)
        {
            ByteStream    byteStream = new ByteStream(buffer, length);
            ServerMessage message    = ServerMessageFactory.CreateMessageByType((ServerMessageType)byteStream.ReadShort());

            if (message != null)
            {
                try
                {
                    message.DecodeHeader(byteStream);
                    message.Decode(byteStream);

                    return(message);
                }
                catch (Exception exception)
                {
                    Logging.Error(string.Format("ServerMessaging::onReceive exception when the decoding of message type {0}, trace: {1}", message.GetMessageType(),
                                                exception));
                }
            }

            return(null);
        }
Example #6
0
        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
            }
        }
Example #7
0
        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);
        }