internal void OnClientReady(NetworkMessage netMsg) { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Client (" + netMsg.conn.connectionId + ") is ready"); // set ready state for this connection ConnectionData connData; if (connectionDataMap.TryGetValue(netMsg.conn.connectionId, out connData)) { connData.isReady = true; ViveShare_Event.server_clientReadyEvent.Invoke(netMsg.conn.connectionId); } // check whether all clients are ready if (AllClientsReady()) { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] All clients are ready"); if (state == ViveNetworkState.Wait_Ready) { state = ViveNetworkState.Wait_GameStart; } ViveShare_Event.server_allClientsReadyEvent.Invoke(); } }
//----------------------------------------------------------------------------- // server life cycle //----------------------------------------------------------------------------- public bool StartServer(int clientNum) { // can only start server when it is inactive if (IsServerActive()) { ViveShare_Log.LogWarning(logLevel, "[ViveShare_Server] Server has started already!"); return(false); } // try to start server on given port number if (!NetworkServer.Listen(portNumber)) { ViveShare_Log.LogError(logLevel, "[ViveShare_Server] Failed to start server on port " + portNumber); ViveShare_Event.server_initFailedEvent.Invoke(); return(false); } ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Server started on port " + portNumber + " , anticipated client = " + clientNum); // initialize connection data anticipatedClientNum = clientNum; connectionDataList = new List <ConnectionData>(); connectionDataMap = new Dictionary <int, ConnectionData>(); RegisterMessageHandlers(); // registor event callback types ViveShare_Event.RegistorEventEntry(); ViveShare_Event.server_initSuccessEvent.Invoke(); state = ViveNetworkState.Wait_Ready; return(true); }
private void DisconnectInternal() { // detect connection time out if (state == ViveNetworkState.Wait_Connect || state == ViveNetworkState.Wait_TrackerRegistry) { ViveShare_Log.LogError(logLevel, "[ViveShare_Client] Disconnect due to connection timeout"); ViveShare_Event.client_connectFailedEvent.Invoke(); } ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Disconnect"); // reset and remove resources if (needTrackerPose) { ViveShare_SyncPose syncPose = Camera.main.gameObject.GetComponent <ViveShare_SyncPose>(); if (syncPose != null) { Destroy(syncPose); } ViveShare_SyncIdentity syncId = Camera.main.gameObject.GetComponent <ViveShare_SyncIdentity>(); if (syncId != null) { Destroy(syncId); } } clientId = -1; ViveShare_Event.client_disconnectEvent.Invoke(); state = ViveNetworkState.Init; }
//----------------------------------------------------------------------------- // client life cycle //----------------------------------------------------------------------------- public bool StartClient() { // can only try connection when connection has not been established, // and previous attempt has failed if ((networkClient != null && networkClient.isConnected) || state != ViveNetworkState.Init) { ViveShare_Log.LogWarning(logLevel, "[ViveShare_Client] Cannot retry connection when client is busy"); return(false); } networkClient = new NetworkClient(); RegistorMessagHandlers(); // registor event callback types ViveShare_Event.RegistorEventEntry(); networkClient.Connect(serverAddr, portNumber); ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Try to connect server (" + serverAddr + ") on port " + portNumber); state = ViveNetworkState.Wait_Connect; return(true); }
internal void OnTrackerRegistryFinished(NetworkMessage netMsg) { // parse message ViveTrackerRegistryReturnMsg msg = netMsg.ReadMessage <ViveTrackerRegistryReturnMsg>(); // assign client id clientId = msg.clientId; // attach sync pose obj to main camera ViveShare_SyncIdentity syncId = Camera.main.gameObject.AddComponent <ViveShare_SyncIdentity>(); syncId.id = msg.syncObjName; syncId.hasAuthority = false; syncId.Register(); ViveShare_SyncPose syncPose = Camera.main.gameObject.AddComponent <ViveShare_SyncPose>(); ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Client id (" + clientId + ") assigned"); ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Tracker registry (" + msg.syncObjName + ") finished"); state = ViveNetworkState.Wait_Ready; // invoke callbacks -- we only think the connection is established at this moment ViveShare_Event.client_connectSuccessEvent.Invoke(); }
internal void OnGameStarted(NetworkMessage netMsg) { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Game start"); ViveShare_Event.gameStartEvent.Invoke(); state = ViveNetworkState.Gaming; }
internal void OnGameEnd(NetworkMessage netMsg) { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Game end"); RemoveSpawnedObjects(); ViveShare_Event.gameEndEvent.Invoke(); state = ViveNetworkState.Wait_Shutdown; }
internal void OnConnect(NetworkMessage netMsg) { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Client connected to server (" + serverAddr + ") on port " + portNumber); // send a request for tracker registry to server (even if not needed) ViveTrackerRegistryRequestMsg trackerRequestMsg = new ViveTrackerRegistryRequestMsg(); trackerRequestMsg.needTrackerPose = needTrackerPose; trackerRequestMsg.serialNumber = serialNumber; trackerRequestMsg.trackerNumber = trackerNumber; networkClient.Send(ViveShareMsgType.TrackerRegistryRequest, trackerRequestMsg); messageSendTimeStamp = Time.time; state = ViveNetworkState.Wait_TrackerRegistry; }
public void SetClientReady() { // can only set client as ready when client is in Wait_Ready state if (state != ViveNetworkState.Wait_Ready) { ViveShare_Log.LogWarning(logLevel, "[ViveShare_Client] Cannot set ready when client is not in Wait_Ready state"); return; } ViveShare_Log.LogInfo(logLevel, "[ViveShare_Client] Client is ready"); // send ready message EmptyMessage msg = new EmptyMessage(); networkClient.Send(MsgType.Ready, msg); ViveShare_Event.client_readyEvent.Invoke(); state = ViveNetworkState.Wait_GameStart; }
internal void OnClientConnectToServer(NetworkMessage netMsg) { // reject client if max number of player connected or game already started if (state > ViveNetworkState.Wait_GameStart || GetConnectedPlayerNum() == anticipatedClientNum) { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Connection attempt (" + netMsg.conn.connectionId + ") rejected"); netMsg.conn.Disconnect(); return; } ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Client (" + netMsg.conn.connectionId + ") connected"); // add a connection data container for this connection ConnectionData connectionData = new ConnectionData(netMsg.conn.connectionId); connectionDataList.Add(connectionData); connectionDataMap.Add(netMsg.conn.connectionId, connectionData); }
public void StartGame() { // can only start game when in Wait_GameStart state if (state != ViveNetworkState.Wait_GameStart) { ViveShare_Log.LogWarning(logLevel, "[ViveShare_Server] Cannot start game -- either the game has started or not all clients are ready"); return; } ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Game start"); // tell clients to start game EmptyMessage msg = new EmptyMessage(); NetworkServer.SendToAll(ViveShareMsgType.GameStarted, msg); ViveShare_Event.gameStartEvent.Invoke(); state = ViveNetworkState.Gaming; }
//----------------------------------------------------------------------------- // networked operation //----------------------------------------------------------------------------- private void FixedUpdate() { // timeout detection if (state == ViveNetworkState.Wait_TrackerRegistry && IsTimeout(Time.time)) { ViveShare_Log.LogError(logLevel, "[ViveShare_Client] Timeout when waiting tracker registry"); networkClient.Disconnect(); DisconnectInternal(); } // messaging if (state == ViveNetworkState.Gaming || state == ViveNetworkState.Wait_Shutdown) { List <ViveShareMessage> msgList = ViveShare_MessageHandler.Instance.GenerateMessagesList(); for (int i = 0; i < msgList.Count; i++) { networkClient.Send(msgList[i].type, msgList[i].body); } } }
internal void OnClientDisconnectFromServer(NetworkMessage netMsg) { // if this disconnection event is due to rejecting illegal connection, do nothing if (GetConnectionData(netMsg.conn.connectionId) == null) { return; } ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Client (" + netMsg.conn.connectionId + ") disconnected"); RemoveConnectionData(netMsg.conn.connectionId); ViveShare_Event.server_clientDisconnectedEvent.Invoke(netMsg.conn.connectionId); // if is in Wait_GameStart state, reset state (since someone left the game before game started) if (state == ViveNetworkState.Wait_GameStart) { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Someone left the game before started, revert to Wait_Ready state"); state = ViveNetworkState.Wait_Ready; } }
public void ShutdownServer() { // can't shut down server if it has not started if (state == ViveNetworkState.Init) { ViveShare_Log.LogWarning(logLevel, "[ViveShare_Server] Cannot shut down server since it has not been started"); return; } // can't shut down server if game is still running if (state == ViveNetworkState.Gaming) { ViveShare_Log.LogWarning(logLevel, "[ViveShare_Server] Cannot shut down server when game is still running"); return; } ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Server shut down"); // clear resources anticipatedClientNum = 0; foreach (NetworkConnection conn in NetworkServer.connections) { if (conn != null) { RemoveConnectionData(conn.connectionId); } } // tell clients to disconnect EmptyMessage msg = new EmptyMessage(); NetworkServer.SendToAll(MsgType.Disconnect, msg); NetworkServer.Shutdown(); ViveShare_Event.server_shutdownEvent.Invoke(); state = ViveNetworkState.Init; }
public void EndGame() { // can only start game when game is running if (state != ViveNetworkState.Gaming) { ViveShare_Log.LogWarning(logLevel, "[ViveShare_Server] Cannot stop game if game has not started"); return; } ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Game end"); RemoveSpawnedObjects(); // tell clients to stop game EmptyMessage msg = new EmptyMessage(); NetworkServer.SendToAll(ViveShareMsgType.GameEnd, msg); ViveShare_Event.gameEndEvent.Invoke(); state = ViveNetworkState.Wait_Shutdown; }
private void RemoveConnectionData(int id) { ConnectionData data; if (connectionDataMap.TryGetValue(id, out data)) { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] RemoveConnectionData for client (" + id + ")"); // destroy tracker object if (data.trackerObject != null) { ViveShare_SyncIdentity syncId = data.trackerObject.GetComponent <ViveShare_SyncIdentity>(); syncId.UnRegister(); Destroy(data.trackerObject); } // destroy data connectionDataList.Remove(data); connectionDataMap.Remove(id); } }
//----------------------------------------------------------------------------- // tracker assignment //----------------------------------------------------------------------------- internal void OnTrakcerResitryRequest(NetworkMessage netMsg) { // parse message ViveTrackerRegistryRequestMsg msg = netMsg.ReadMessage <ViveTrackerRegistryRequestMsg>(); // check connectivity int connId = netMsg.conn.connectionId; ConnectionData connData = GetConnectionData(connId); if (connData == null) { return; } // if need to assign a tracker to client string trackerPoseObjName = ""; if (msg.needTrackerPose) { TrackerRole trackerRole = TryToBindTracker(msg.serialNumber, msg.trackerNumber); // if failed, tell client to disconnect if (trackerRole == TrackerRole.Invalid) { ViveShare_Log.LogError(logLevel, "[ViveShare_Server] Failed to assign tracker for client (" + netMsg.conn.connectionId + ")"); netMsg.conn.Disconnect(); return; } // if succeeded, save assigned role and initialize sync pose object else { ViveShare_Log.LogInfo(logLevel, "[ViveShare_Server] Assign tracker (" + trackerRole.ToString() + ") to client (" + netMsg.conn.connectionId + ")"); connData.trackerRole = trackerRole; trackerPoseObjName = trackerRole.ToString(); // create pose tracker and attach sync param object to it GameObject trackerObj = new GameObject(trackerPoseObjName); VivePoseTracker poseTracker = trackerObj.AddComponent <VivePoseTracker>(); poseTracker.viveRole.SetEx <TrackerRole>(trackerRole); ViveShare_SyncIdentity syncId = trackerObj.AddComponent <ViveShare_SyncIdentity>(); syncId.id = trackerPoseObjName; syncId.hasAuthority = true; syncId.Register(); trackerObj.AddComponent <ViveShare_SyncPose>(); if (cameraRig != null) { trackerObj.transform.parent = cameraRig.transform; } connData.trackerObject = trackerObj; } } // return "finished" message ViveTrackerRegistryReturnMsg returnMsg = new ViveTrackerRegistryReturnMsg(); returnMsg.syncObjName = trackerPoseObjName; returnMsg.clientId = connId; NetworkServer.SendToClient(netMsg.conn.connectionId, ViveShareMsgType.TrackerRegistryFinished, returnMsg); // invoke callbacks -- we only think the connection is established at this moment ViveShare_Event.server_clientConnectedEvent.Invoke(netMsg.conn.connectionId); }