/// <summary> /// Wartet auf die nächste SMCP-Message, die über den angegebenen NetworkStream /// </summary> /// <param name="stream">Der Stream, über welchen die Nachrichten ankommen</param> /// <returns>Die erhaltene SMCP-Message</returns> public static SMCPMessage ReadNextMessage(NetworkStream stream) { SMCPMessage msg = new SMCPMessage(); byte[] header = new byte[8]; //read header first if (stream.Read(header, 0, 8) < 8) { return(null); } //unmarshal header information int length = BitConverter.ToInt32(header, 0); msg.SenderID = BitConverter.ToInt16(header, 4); msg.Multicast = BitConverter.ToBoolean(header, 6); msg.ActionID = header[7]; //Wait for and read DATA segment byte[] message = new byte[length]; int amountRead = 0; while (length > 0) { amountRead = stream.Read(message, amountRead, length); length -= amountRead; } msg.Data = message; return(msg); }
/// <summary> /// Verarbeitet ankommende SMCP-Nachrichten /// </summary> /// <param name="sender"></param> /// <param name="e">Die SMCP-Nachricht</param> private void Connection_SMCPMessageReceived(object sender, Protocol.SMCPMessage e) { switch ((SMCPAction)e.ActionID) { case SMCPAction.VIEW_CHANGED: ///Die Ansicht wurde im Netzwerk verändert -> auch auf diesem Client ändern ChangeView(e.GetData <int>(this.Connection)); break; case SMCPAction.REQUEST_ITEM_ID: { // Einer der Clients hat eine neue Item-ID angefragt -> Falls es sich hier um einen Server handelt, // schicke eine neue ID zurück if (this.Connection.IsServer) { SMCPMessage respone = Connection.CreateMessage(UserStory.NextUserStoryID++, false, SMCPAction.ASSIGN_ITEM_ID); Connection.SendMessage(respone, Connection.ConnectedClients[e.SenderID]); } } break; case SMCPAction.ASSIGN_ITEM_ID: //Neue Item-ID wurde angefragt und erhalten -> weise sie einem der wartenden Items zu //Client: Item Teilen - Schritt 2 / 3 ItemBase item = WaitingForID.Dequeue(); if (item != null) { item.ItemID = e.GetData <short>(this.Connection); ShareItemFinally(item); } break; case SMCPAction.ADD_ITEM: { //Neues Item erhalten, zu den Items der Oberfläche hinzufügen AddItem(e.GetData <ItemBase>(this.Connection)); } break; case SMCPAction.START_EDITING: //In den (Readonly)-Editiermodus eines Items wechseln ChangeEditorState(e.GetData <ItemBase>(this.Connection).ItemID, true); break; case SMCPAction.END_EDITING: //Den Editiermodus wieder beenden ChangeEditorState(e.GetData <ItemBase>(this.Connection).ItemID, false); break; case SMCPAction.UPDATE_ITEM: //Die Daten eines Items aktualisieren (wurde von einem anderem Teilnehmer initiiert) UpdateItem(e.GetData <ItemBase>(this.Connection)); break; case SMCPAction.FOCUS_ON_ITEM: //Ein Item in den Fokus aller Teilnehmer rücken (wurde von einem anderem Teilnehmer initiiert) RequestFocus(e.GetData <short>(this.Connection)); break; case SMCPAction.REMOVE_ITEM: //Ein Item wurde von einem anderen Teilnehmer gelöscht RemoveItem(e.GetData <short>(this.Connection)); break; case SMCPAction.ALL_ITEMS: //Liste von Items erhalten -> Aktuelle Datenbank durch Internet Datenbank ersetzen Surface.Invoke(() => { SendableDatabase sdb = e.GetData <SendableDatabase>(this.Connection); sdb.LoadIntoDB(Surface.Database); }); break; } }