// SERVER CONNECTION WORK BEGINS HERE /// <summary> /// Initial handshake with the server /// </summary> /// <param name="state"></param> public void FirstContact(SocketState state) { state.callMe = ReceiveStartup; StaticNetworking.Send(state.Socket, UsernameTextBox.Text + "\n"); }
/// <summary> /// Process incoming messages from the server. /// </summary> /// <param name="state"></param> private void ProcessMessage(SocketState state) { string message; lock (state) { message = state.builder.ToString(); string[] messages = message.Split((char)3); foreach (string msg in messages) { if (msg == "") { break; } string[] msg2 = msg.Split(' '); string command = msg2[0]; if (command == "change") { //get cell name and contents from message char[] delimiters = new char[] { ' ', ':' }; string[] msg_parts = msg.Split(delimiters, 3); string cell_name = msg_parts[1]; string contents = msg_parts[2]; //set the contents of the cell GetCellPosition(cell_name, out int row, out int col); SetCell(row, col, contents); } else if (command == "ping") { //if (msg == "ping ") //{ SendMessage("ping_response " + ((char)3)); //} //else if (msg == "ping_response ") //{ //timer reset -- not sure this is right //serverTimer.Stop(); //serverTimer.Start(); //pingMisses = 0; //} //break; } else if (command == "ping_response") { pingMisses = 0; } else if (command == "disconnect") { MessageBox.Show("Server terminated connection - Window " + winNum); HandleDisconnect(); } else if (command == "unfocus") { char[] delimiters2 = new char[] { ' ' }; string[] msg_parts2 = msg.Split(delimiters2); string user_id = msg_parts2[1]; if (clientFocus.ContainsKey(user_id)) { string cell_name = clientFocus[user_id]; GetCellPosition(cell_name, out int row, out int col); spreadsheetPanel1.SetUnfocus(cell_name, row, col); } } else if (command == "focus") { char[] delimiters3 = new char[] { ' ', ':' }; string[] msg_parts3 = msg.Split(delimiters3); string cell_name = msg_parts3[1]; string user_id = msg_parts3[2]; clientFocus[user_id] = cell_name; GetCellPosition(cell_name, out int row, out int col); spreadsheetPanel1.SetFocus(cell_name, row, col); } else { //command is not a full command, so leave it in the state.builder. break; //then still go and get data } state.builder.Remove(0, msg.Length + ((char)3).ToString().Length); } } Network.GetData(state); }
/// <summary> /// Processes a full state message. Assigns processMessage() as the socket state's callme when finished. /// </summary> /// <param name="state"></param> private void HandleFullState(SocketState state) { state.callMe = ProcessMessage; string message; lock (state) { message = state.builder.ToString(); } state.builder.Clear(); MethodInvoker FMInvoker = new MethodInvoker(() => { FilePanel.Visible = false; }); if (message.Contains(((char)3).ToString())) { if (message.Length < 20 && message.Contains("file_load_error")) { MessageBox.Show("Could not open/create spreadsheet!"); Open_FileMenu.Enabled = true; state.callMe = HandleFullState; //TO DO //does file_load_error need to call getData still? or can we return? //assumption is opening up the file menu again does sendspreadsheetselection and get data return; } if (message.Contains("ping " + ((char)3))) { //we can *probably* discard the pings that are in this message, the server //will send more before we time out message.Remove(message.IndexOf("ping " + ((char)3))); } if (message.Contains("full_state ")) { //empty full state message ("full_state char3") is 12 if (message.Length > 12) { //full_state A6:3\nB4:2\n((char3)) //remove "full_state " and the terminating character message = message.Substring(10, message.Length - 11); string[] cells = message.Split('\n'); //split the cell name and value then set the cell. foreach (string cell in cells) { if (cell == "") { continue; } string[] cellAndval = cell.Split(':'); string cellName = cellAndval[0]; string cellVal = cellAndval[1]; //cellName = cellName.Trim(' '); cellVal = cellVal.TrimStart(' '); int[] colRow = GetCellPosition(cellName); SetCell(colRow[1], colRow[0], cellVal); } } //TO DO put back (also on server) pingTimer.Start(); //serverTimer.Start(); this.Invoke(FMInvoker); } } Network.GetData(state); }
private void send_edit_to_server(SocketState ss, string s) { Networking.Send(ss, s); }
/// <summary> /// A command was received from the server, we need to process it /// </summary> /// <param name="ss"></param> public void Spreadsheet_ProcessMessage(SocketState ss) { //lock (spreadsheet) { string allData = ss.sb.ToString(); string[] parts = allData.Split((Char)3); if (parts.Length == 1) { return; } foreach (string data in parts) { if (data == ((Char)3).ToString()) { ss.sb.Remove(0, data.Length); continue; } //It's an incomplete message, wait for later if (data.StartsWith("ping_response")) { PingDelay = 0; } else if (data.StartsWith("ping") && data.Length < 12) { // Networking.Send(serverSocket, "ping_response "); send_ping_response(); } else if (data.StartsWith("change ")) { string cellName = data.Substring("change ".Length, data.IndexOf(":") - "change ".Length); try { string cellContents = data.Substring(data.IndexOf(":") + 1); ISet <string> dependents = Spread.SetContentsOfCell(cellName, cellContents); ConvertNameToColRow(cellName, out int dependentCol, out int dependentRow); // Update the displayed cell info for the newly modified cell MethodInvoker invoker = new MethodInvoker(() => DisplayCellInfo(dependentCol, dependentRow)); //DisplayCellInfo(dependentCol, dependentRow); // Updates the displayed values of each of the dependent cells (this includes the modified cell) UpdateDependentCells(dependents); } catch (CircularException) { string cellContents = ""; MessageBox.Show("There is a circular dependency. Unacceptable"); cell_edit_to_server(ServerSocket, cellName, cellContents); ISet <string> dependents = Spread.SetContentsOfCell(cellName, cellContents); ConvertNameToColRow(cellName, out int dependentCol, out int dependentRow); // Update the displayed cell info for the newly modified cell MethodInvoker invoker = new MethodInvoker(() => DisplayCellInfo(dependentCol, dependentRow)); //DisplayCellInfo(dependentCol, dependentRow); // Updates the displayed values of each of the dependent cells (this includes the modified cell) UpdateDependentCells(dependents); } } else if (data.StartsWith("focus ")) { string cellName = data.Substring("focus ".Length, data.IndexOf(":") - "focus ".Length); string id = data.Substring(data.IndexOf(":") + 1); spreadsheetPanel1.GetSelection(out int col, out int row); if (cellName != ConvertColRowToName(col, row)) { spreadsheetPanel1.FocusCell(cellName, id); } } else if (data.StartsWith("unfocus")) { string id = data.Substring("unfocus ".Length); spreadsheetPanel1.UnfocusCell(id); } if (data.Length <= ss.sb.Length) { ss.sb.Remove(0, data.Length); } } Networking.GetData(ss); } }
/// <summary> /// Called when the Client's "View" code requests more data. /// </summary> /// <param name="state"></param> public static void GetData(SocketState state) { state.Socket.BeginReceive(state.MessageBuffer, 0, state.MessageBuffer.Length, SocketFlags.None, ReceiveCallback, state); }