Custom State-Storage Options
If the provided state-storage strategies are insufficient for your needs, you can implement your own state storage. For example, you might want to store state in a file or database. The SessionStores application provides an example of a state-storage mechanism that uses the file system. Let's take a look at how it's done.In WebObjects, an application saves and restores sessions by sending the session store object these messages:
- saveSession:
- restoreSession
// WebScript StateStorage FileSessionStore.wos @interface FileSessionStore:NSObject { id archiveDirectory; } - init; - archiveFileForSessionID:aSessionID; - archiveForSessionID:aSessionID; - restoreSession; - saveSession:aSession; @endThese methods have the following implementation:
@implementation FileSessionStore - init { self = [super init]; archiveDirectory = [WOApp pathForResourceNamed:@"SessionArchives" ofType:nil]; return self; } - archiveFileForSessionID:aSessionID { return [NSString stringWithFormat:@"%@/%@", archiveDirectory, aSessionID]; } - archiveForSessionID:aSessionID { id archiveFile = [self archiveFileForSessionID:aSessionID]; return [NSData dataWithContentsOfFile:archiveFile]; } - restoreSession { id request = [[WOApp context] request]; id archivedSession; id restoredSession; // Allow requests in this session to go to any application instance. [[WOApp context] setDistributionEnabled:YES]; // Get archived session (as an NSData object) archivedSession = [self archiveForSessionID:[request sessionID]]; // Unarchive session restoredSession = [NSUnarchiver unarchiveObjectWithData:archivedSession]; return restoredSession; } - saveSession:aSession { id request = [[WOApp context] request]; // Store data corresponding to session only if necessary. if (![aSession isTerminating] && ![request isFromClientComponent]) { id sessionData = [NSArchiver archivedDataWithRootObject:aSession]; id sessionFilePath = [self archiveFileForSessionID:[aSession sessionID]]; [sessionData writeToFile:sessionFilePath atomically:YES]; } } @endAs you can see, when the FileSessionStore receives a saveSession: message, it checks whether the session object needs to be archived, and if so, it asks NSArchiver to create a binary archive of the session object and all of the components it contains. It then invokes its own archiveFileForSessionID: to determine the path for the archive file. Finally, it writes the data to the file. Notice that the session data is written to a file whose name is the session ID itself.
In this implementation, restoreSession restores the state for a particular session. An interesting point in the restoreSession method implementation is the setDistributionEnabled: message to the WOContext object (Context in Java). This method enables application load balancing. As you learned in the earlier section "State in the Server", when state is stored in the server, all requests from a particular session must access the same application instance on the same machine. In this example, because session state is stored in the file system and not in the application's memory, any application instance can handle any request. The setDistributionEnabled: method enables application load balancing by allowing any application instance to respond to any request.
Table of Contents Next Section