Perché non riesco a condividere lo stato di Sessione tra 2 applicazioni web con StateServer?Che cosa mi manca?

StackOverflow https://stackoverflow.com/questions/3292359

Domanda

Sto avendo difficoltà a raggiungere 2 identici ASP.NET applicazioni MVC per condividere la stessa Sessione con una Sessione di StateServer.La ragione per cui sto cercando di fare questo è che alla fine sarà la distribuzione di questa app su 3 server web che hanno bisogno di condividere lo stesso stato.Abbiamo bisogno di utilizzare StateServer perché stiamo cercando di ridurre al minimo l'uso del db per non correlati ai dati di archiviazione.

Il Setup:

Ho distribuito la stessa base di codice a http://localhost/App1 e http://localhost/App2

entrambi sono identici Web.I file di configurazione con il seguente:

<system.web>
<sessionState mode="StateServer" 
              cookieless="false" 
              timeout="20" 
              stateConnectionString="tcpip=127.0.0.1:42424" />
              //stateConnectionString="tcpip=192.168.1.52:42424" /> // also doesn't work
<machineKey 
  validationKey="8B9F68D0CC730F6F046D0173021C34B1A0D9A01C21D8E4D4A7A1DFF38332DEE8CBBAFEA503C18776614EE9D4F7EEA7E5D2D5571630547D822485A27B1EF53AC1"
  decryptionKey="60009563EFCFC594FD1BC46684943AA398EE70412A624B2EB488BBB071F15ECF"
  validation="SHA1" decryption="AES" />

Ho usato questo strumento per generare le chiavi della macchina

Il Test:

Ho messo la seguente uno dei miei Controller per testare se funziona:

ViewData["mode"] = requestContext.HttpContext.Session.Mode.ToString();

string timestamp = DateTime.Now.ToString();
if (requestContext.HttpContext.Session["timestamp"] == null)
{
    requestContext.HttpContext.Session["timestamp"] = timestamp;
}

ViewData["timestamp"] = requestContext.HttpContext.Session["timestamp"].ToString();
ViewData["realtime"] = timestamp;

con questo in vista:

<p>
    Mode: <%= ViewData["mode"].ToString() %>
</p>
<p>
    Time: <%= ViewData["timestamp"].ToString() %>
</p>
<p>
    real time: <%= ViewData["realtime"].ToString() %>
</p>

Il Risultato:

Per entrambe le distribuzioni, quando il primo caricamento della pagina vedo che la modalità è StateServer e il timestamp è sempre impostato per lo stesso tempo come il realtime valore..Tuttavia, se questa è lavoro, solo la prima pagina deve avere lo stesso tempo come il realtime valore.Il secondo di caricamento della pagina dovrebbe leggere il StateServer perché il valore timestamp non è più nullo, e la visualizzazione del valore del tempo.Ma, invece, è la visualizzazione in tempo reale del valore di nuovo.

Quando mi si aggiorna la pagina, ho il timestamp rimane lo stesso e in tempo reale il valore è sempre in aggiornamento.Questo indica che il timestamp è stata salvata la Sessione, ma il valore di timestamp è sempre diversa per entrambe le distribuzioni quando dovrebbe essere lo stesso, quindi questo indica che la Sessione non viene condivisa.

Qualcuno può indicare se sto facendo qualcosa di sbagliato o se c'è qualcos'altro che devo fare per ottenere questo lavoro?Grazie

È stato utile?

Soluzione

Per impostazione predefinita sessione non può essere condivisa tra le diverse applicazioni.Da quello che posso vedere si hanno due distinte applicazioni App1 e App2 in esecuzione nel separare le directory virtuali e, probabilmente, anche i singoli pool di applicazioni, quindi non aspettatevi di sessione di condivisione tra di loro.

Come sempre ci sono soluzioni alternative che si possono trovare utili.Come si può vedere usando un hack (di riflessione) per eludere la ASP.NET il team di designer di determinazione di non esporre determinate classi e le proprietà e rendere la nostra vita come gli sviluppatori difficile.

Altri suggerimenti

In realtà è possibile condividere le sessioni di utilizzo di Sql server in modalità.

Prova questo:-

Ho appena cambiato la procedura ovvero

USE ASPState
GO

ALTER PROCEDURE dbo.TempGetAppID
    @appName tAppName,
    @appId int OUTPUT
AS

    -- start change

    -- Use the application name specified in the connection for the appname if specified
    -- This allows us to share session between sites just by making sure they have the
    -- the same application name in the connection string.
    DECLARE @connStrAppName nvarchar(50)
    SET @connStrAppName = APP_NAME()

    -- .NET SQLClient Data Provider is the default application name for .NET apps
    IF (@connStrAppName <> '.NET SQLClient Data Provider')
        SET @appName = @connStrAppName

    -- end change

SET @appName = LOWER(@appName)
SET @appId = NULL

SELECT @appId = AppId
FROM [ASPState].dbo.ASPStateTempApplications
WHERE AppName = @appName

IF @appId IS NULL BEGIN
BEGIN TRAN 

SELECT @appId = AppId
FROM [ASPState].dbo.ASPStateTempApplications WITH (TABLOCKX)
WHERE AppName = @appName

IF @appId IS NULL
BEGIN
EXEC GetHashCode @appName, @appId OUTPUT

INSERT [ASPState].dbo.ASPStateTempApplications
VALUES
(@appId, @appName)

IF @@ERROR = 2627 
BEGIN
DECLARE @dupApp tAppName

SELECT @dupApp = RTRIM(AppName)
FROM [ASPState].dbo.ASPStateTempApplications 
WHERE AppId = @appId

RAISERROR('SQL session state fatal error: hash-code collision between applications ''%s'' and ''%s''. Please rename the 1st application to resolve the problem.', 
18, 1, @appName, @dupApp)
END
END

COMMIT
END

RETURN 0 
GO

e poi modificato web.config come:-

<sessionState mode="SQLServer" sqlConnectionString="Data Source=.;Integrated Security=True;Application Name=TEST" cookieless="false" timeout="20"></sessionState>
   <httpRuntime targetFramework="4.5"/>

È necessario aggiungere il Nome dell'Applicazione e che devono essere uguali per tutti l'applicazione per cui si desidera condividere la stessa sessione.

Grazie.

Aggiornamento:Ecco un post precedente ho risposto su questo stesso argomento Le sessioni di condivisione tra le applicazioni utilizzando il ASP.NET Servizio di Stato Sessione

Come già sottolineato, i dati della Sessione ambito di applicazione.Che è l'Applicazione che consente di creare in IIS.Così due applicazioni con lo stesso id di sessione non sarà la condivisione di una stessa sessione, a causa dell'applicazione di scoping.

Come un'idea alternativa che potrebbe o non potrebbe essere fattibile.È possibile creare una directory principale dell'applicazione e il codice per D:\App1 e D:\App2 in due sottocartelle.

d:\Root
  web.config
  \App1
     default.aspx
     ...
  \App2
     default.aspx
     ...

Quindi in IIS è possibile creare un'Applicazione che punta a d: oot.

È inoltre possibile creare un'Applicazione in IIS e quindi sotto l'Applicazione consente di creare due directory, una che punta a D:\App1 e l'altro D:\App2 poi si può anche condividere una singola web.config a livello di Applicazione.È fondamentale che i due directory virtuali sono solo virtuali e non creato come Applicazioni.

Così si harddisk layout potrebbe essere qualcosa di simile a questo

D:\Root
  web.config

D:\App1
  default.aspx
  ...

D:\App2
  default.aspx
  ...

Creare la directory radice dell'applicazione che punta a D: oot e poi sotto l'applicazione di creare due directory virtuali App1 che punta a D:\App1 e App2 che punta a D:\App2.

L'effetto in entrambi i casi, è che in realtà hanno una applicazione divisa in due sezioni, entrambe nella stessa Sessione di ambito, pertanto, il codice sia possibile condividere i dati della stessa sessione.

È inoltre necessario assicurarsi che il percorso dell'applicazione per l'applicazione deve essere lo stesso su entrambi i server web.C'è un vecchio articolo che potrebbe essere di aiuto

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q325056

Stiamo vivendo un problema simile, tranne che si utilizza IIS 7.5 e i percorsi delle applicazioni sono nascosti a noi (non uso la metabase di più).Qualcuno sa un modo di risoluzione dei problemi con IIS 7.5?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top