private void RefreshDatabaseInfo() { m_stream.Write((byte)ServerCommand.GetAllDatabases); m_stream.Flush(); var command = (ServerResponse)m_stream.ReadUInt8(); switch (command) { case ServerResponse.UnhandledException: string exception = m_stream.ReadString(); throw new Exception("Server UnhandledExcetion: \n" + exception); case ServerResponse.ListOfDatabases: int cnt = m_stream.ReadInt32(); var dict = new Dictionary <string, DatabaseInfo>(); while (cnt > 0) { cnt--; var info = new DatabaseInfo(m_stream); dict.Add(info.DatabaseName.ToUpper(), info); } m_databaseInfos = dict; break; default: throw new Exception("Unknown server response: " + command.ToString()); } }
/// <summary> /// This function will verify the connection, create all necessary streams, set timeouts, and catch any exceptions and terminate the connection /// </summary> /// <remarks></remarks> public void ProcessClient() { try { long code = m_rawStream.ReadInt64(); if (code != 0x2BA517361121L) { m_rawStream.Write((byte)ServerResponse.UnknownProtocol); m_rawStream.Flush(); return; } bool useSsl = m_rawStream.ReadBoolean(); if (RequireSSL) { useSsl = true; } m_rawStream.Write((byte)ServerResponse.KnownProtocol); m_rawStream.Write(useSsl); if (!m_authentication.TryAuthenticateAsServer(m_rawStream, useSsl, out m_secureStream, out m_permissions)) { return; } m_stream = new RemoteBinaryStream(m_secureStream); m_stream.Write((byte)ServerResponse.ConnectedToRoot); m_stream.Flush(); ProcessRootLevelCommands(); } catch (Exception ex) { try { m_stream.Write((byte)ServerResponse.UnhandledException); m_stream.Write(ex.ToString()); m_stream.Flush(); } catch (Exception) { } Log.Publish(MessageLevel.Warning, "Socket Exception", "Exception occured, Client will be disconnected.", null, ex); } finally { Dispose(); Log.Publish(MessageLevel.Info, "Client Disconnected", "Client has been disconnected"); m_stream = null; } }
/// <summary> /// This function will verify the connection, create all necessary streams, set timeouts, and catch any exceptions and terminate the connection /// </summary> /// <returns>True if successful, false if needing to exit the socket.</returns> public bool RunDatabaseLevel() { while (true) { ServerCommand command = (ServerCommand)m_stream.ReadUInt8(); switch (command) { case ServerCommand.SetEncodingMethod: try { m_encodingMethod = Library.CreateStreamEncoding <TKey, TValue>(new EncodingDefinition(m_stream)); } catch { m_stream.Write((byte)ServerResponse.UnknownEncodingMethod); m_stream.Flush(); return(false); } m_stream.Write((byte)ServerResponse.EncodingMethodAccepted); m_stream.Flush(); break; case ServerCommand.Read: if (!ProcessRead()) { return(false); } break; case ServerCommand.DisconnectDatabase: m_sortedTreeEngine.Dispose(); m_sortedTreeEngine = null; m_stream.Write((byte)ServerResponse.DatabaseDisconnected); m_stream.Flush(); return(true); case ServerCommand.Write: ProcessWrite(); break; case ServerCommand.CancelRead: break; default: m_stream.Write((byte)ServerResponse.UnknownDatabaseCommand); m_stream.Write((byte)command); m_stream.Flush(); return(false); } } }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> /// <filterpriority>2</filterpriority> public void Dispose() { if (!m_disposed) { m_client.m_writer = null; m_disposed = true; m_encodingMode.WriteEndOfStream(m_stream); m_stream.Flush(); } }
/// <summary> /// This function will process any of the packets that come in. It will throw an error if anything happens. /// This will cause the calling function to close the connection. /// </summary> /// <remarks></remarks> private void ProcessRootLevelCommands() { m_host = SnapClient.Connect(m_server); while (true) { ServerCommand command = (ServerCommand)m_stream.ReadUInt8(); switch (command) { case ServerCommand.GetAllDatabases: var info = m_host.GetDatabaseInfo(); m_stream.Write((byte)ServerResponse.ListOfDatabases); m_stream.Write(info.Count); foreach (var i in info) { i.Save(m_stream); } m_stream.Flush(); break; case ServerCommand.ConnectToDatabase: string databaseName = m_stream.ReadString(); Guid keyTypeId = m_stream.ReadGuid(); Guid valueTypeId = m_stream.ReadGuid(); if (!m_host.Contains(databaseName)) { m_stream.Write((byte)ServerResponse.DatabaseDoesNotExist); m_stream.Write("Database Does Not Exist"); m_stream.Flush(); return; } var database = m_host.GetDatabase(databaseName); var dbinfo = database.Info; if (dbinfo.KeyTypeID != keyTypeId) { m_stream.Write((byte)ServerResponse.DatabaseKeyUnknown); m_stream.Write("Database Key Type Is Invalid"); m_stream.Flush(); return; } if (dbinfo.ValueTypeID != valueTypeId) { m_stream.Write((byte)ServerResponse.DatabaseValueUnknown); m_stream.Write("Database Value Type Is Invalid"); m_stream.Flush(); return; } var type = typeof(SnapStreamingServer); var method = type.GetMethod("ConnectToDatabase", BindingFlags.NonPublic | BindingFlags.Instance); var reflectionMethod = method.MakeGenericMethod(database.Info.KeyType, database.Info.ValueType); var success = (bool)reflectionMethod.Invoke(this, new object[] { database }); if (!success) { return; } break; case ServerCommand.Disconnect: m_stream.Write((byte)ServerResponse.GoodBye); m_stream.Write("Good bye!"); m_stream.Flush(); return; default: m_stream.Write((byte)ServerResponse.UnknownCommand); m_stream.Write((byte)command); m_stream.Flush(); return; } } }