Principales respuestas
SignalR y Session

Pregunta
-
Hola espero que esten bien.
Tengo una aplicación la cual utiliza el SignalR para hacer consulta en la Base de datos tengo una Clase Hub
Dentro tengo funciones las cuales hacen las operaciones, el problema que en una funcion necesito acceder a un dato que tendo en una variable de session "Session("IDProv")" pero me dice "Error de instancia de Objeto"
de igual manera ya lo coloque asi:
HttpContext.Current.Session("IDProv")
y sigue el mismo error.
Como puedo acceder a esa variable de session?
Public Sub NotificationST() Dim IDP As Integer = HttpContext.Current.Session("IDProv") '<============ ¿COMO ACCESO A ESTA VARIABLE Dim JSNotificacion = Nothing Dim QueryString As String = "DECLARE @CTV AS INT, @FTV AS BIT EXEC dbo.NotificationST @IDP, @CTV OUT, @FTV OUT SELECT @CTV AS CTV, @FTV AS FTV" Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("CNX").ConnectionString) connection.Open() Using command As New SqlCommand(QueryString, connection) command.Parameters.AddWithValue("IDP", IDP) command.Notification = Nothing Dim Dependency As New SqlDependency(command) AddHandler Dependency.OnChange, AddressOf dependency_Onchange If connection.State = ConnectionState.Closed Then connection.Open() End If Dim Reader As SqlDataReader = command.ExecuteReader() If Reader.Read Then JSNotificacion = New With {.CTV = IIf(Reader("CTV") = 0, "", Reader("CTV")), .FTV = Reader("FTV")} End If End Using Clients.All.notificationST(JSNotificacion) End Using End Sub
Respuestas
-
hola
Hasta donde conozco no puedes acceder a la Session en SignalR
No access to the Session information through SignalR Hub
es mas si necesitas accederlo es porque algo esta mal planteado, deberias pensar ese codigo para todos los proveedores y no para uno en concreto, pudiendo enviarles notificaciones si hace falta
Si la idea es solo notificar a determinados proveedores deberia ser configurable, ya sea que lo tomes del .config que proveedores pueden ser notificados de cambios o quizas con algun campos en la tabla proveedor que indique si se notifican o no
pero a donde voy es que las notificaciones de signalR deberian ser mas genericas y no depende de la Session
Ademas un procedure no se ejecuta de esa forma, no se usa el EXEC, tienes que definir el CommandType
saludos
Leandro Tuttini
Blog
MVP Profile
Buenos Aires
Argentina- Marcado como respuesta Folanc miércoles, 24 de mayo de 2017 15:02
Todas las respuestas
-
El problema es que la sesión se reconoce gracias a la cookie de sesión. Esa cookie es transmitida desde el navegador al servidor en cada navegación por http, y gracias a ella el servidor distingue cuál de todas las sesiones es la que tiene que usar. Pero cuando usas SignalR, no son peticiones http que contengan las cookies, sino que es un enlace "binario" a través de websockets. No se envía la cookie al servidor en cada llamada. Por lo tanto, el servidor no tiene forma de saber de qué sesión se trata. Tienes que usar algún otro mecanismo para identificar al cliente, en lugar de usar el Session. Por ejemplo, puedes añadir un parámetro a la función y que el cliente la llame pasando ahí algo que reconozcas en el servidor y que te permita recoger los datos asociados a ese cliente concreto.
- Propuesto como respuesta Brayan De La Cruz lunes, 22 de mayo de 2017 0:05
-
hola
Hasta donde conozco no puedes acceder a la Session en SignalR
No access to the Session information through SignalR Hub
es mas si necesitas accederlo es porque algo esta mal planteado, deberias pensar ese codigo para todos los proveedores y no para uno en concreto, pudiendo enviarles notificaciones si hace falta
Si la idea es solo notificar a determinados proveedores deberia ser configurable, ya sea que lo tomes del .config que proveedores pueden ser notificados de cambios o quizas con algun campos en la tabla proveedor que indique si se notifican o no
pero a donde voy es que las notificaciones de signalR deberian ser mas genericas y no depende de la Session
Ademas un procedure no se ejecuta de esa forma, no se usa el EXEC, tienes que definir el CommandType
saludos
Leandro Tuttini
Blog
MVP Profile
Buenos Aires
Argentina- Marcado como respuesta Folanc miércoles, 24 de mayo de 2017 15:02
-
HOla Muchas gracias a los dos por darme respues, tomare muy encuenta sus comentarios.
y si leandro lo que quiero hacer es como seran varios proveedores en mi Base, quiero que solo le llegue la notificacion o actualización al proveedor que le estoy dando seguimiento, no usar el "Clients.All" si no el "Clients.client", vaya lo que no tengo claro aun o no he visualizado porque aun inicie con el SignalR y estoy buscando información es como usar el ConnectionID, como almacenarlo o como vincularlo al proveedor, pues imagino que el ConnectionID cambia con cada inicio de sesión, o tu me recomiendas usar solo el "Clients.all"?.
Con respecto a lo del procedimiento almacenado, investigare esa parte, ya que asi como lo tengo es un ejemplo que encontre.
muchas gracias por sus respuestas.
-
Ya hice el cambio del procedimiento almacenado es el siguiente:
Public Sub NotificationCCP() Dim JSNotificacion = Nothing '"DECLARE @CTV AS INT, @FTV AS BIT EXEC dbo.NotificationCCP @CTV OUT, @FTV OUT SELECT @CTV AS CTV, @FTV AS FTV" Dim QueryString As String = "NotificationCCP" Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("CNX").ConnectionString) connection.Open() Using command As New SqlCommand(QueryString, connection) command.CommandType = CommandType.StoredProcedure Dim CTV As SqlParameter = command.Parameters.Add("CTV", SqlDbType.Int) CTV.Direction = ParameterDirection.Output Dim FTV As SqlParameter = command.Parameters.Add("FTV", SqlDbType.Bit) FTV.Direction = ParameterDirection.Output command.Notification = Nothing Dim Dependency As New SqlDependency(command) AddHandler Dependency.OnChange, AddressOf dependency_Onchange If connection.State = ConnectionState.Closed Then connection.Open() End If command.ExecuteNonQuery() 'Dim Reader As SqlDataReader = command.ExecuteReader() 'If Reader.Read Then 'JSNotificacion = New With {.CTV = Reader("CTV"), .FTV = Reader("FTV")} 'End If JSNotificacion = New With {.CTV = CTV.Value, .FTV = FTV.Value} End Using End Using Clients.All.notificationCCP(JSNotificacion) End Sub
Por favor si omití algo espero puedan decirme.
-
hola
si usas el
command.CommandType = CommandType.StoredProcedure
entonces no necesitas definir los parametros, el comand seria
Dim JSNotificacion As String= "dbo.NotificationCCP"
asi directo los parametros a la coleccion Parameters del command, aunque no veo donde asignas el CTV y FTV al command
saludos
Leandro Tuttini
Blog
MVP Profile
Buenos Aires
Argentina -
Hola de nuevo, tengo los cambios
Public Sub NotificationCCP() Dim JSNotificacion = Nothing Dim QueryString As String = "dbo.NotificationCCP" Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("CNX").ConnectionString) connection.Open() Using command As New SqlCommand(QueryString, connection) command.CommandType = CommandType.StoredProcedure Dim CTV As SqlParameter = command.Parameters.Add("CTV", SqlDbType.Int) CTV.Direction = ParameterDirection.Output Dim FTV As SqlParameter = command.Parameters.Add("FTV", SqlDbType.Bit) FTV.Direction = ParameterDirection.Output command.Notification = Nothing Dim Dependency As New SqlDependency(command) AddHandler Dependency.OnChange, AddressOf dependency_Onchange If connection.State = ConnectionState.Closed Then connection.Open() End If command.ExecuteNonQuery() JSNotificacion = New With {.CTV = CTV.Value, .FTV = FTV.Value} End Using End Using Clients.All.notificationCCP(JSNotificacion) End Sub
Con respecto a tu pregunta de la asignación de los parametros CTV y FTV, si agrego un "command.Parameters.Add(CTV)" al momento de la ejecución me da un error, así como lo tengo me devuelve los valores, esto lo tome de un ejemplo en esta pagina: Como llamar un procedimiento
Agradezco cualquier comentario.
-
hola
>>al momento de la ejecución me da un error, así como lo tengo me devuelve los valores
ahh ok no habia visto que el Add() lo asignabas a la variable, por lo general simpre veia que se usa
Dim CTV As New SqlParameter("CTV", SqlDbType.Int) CTV.Direction = ParameterDirection.Output command.Parameters.Add(CTV)
pero tu forma tambien es correcta
saludos
Leandro Tuttini
Blog
MVP Profile
Buenos Aires
Argentina -
Hola, Leandro aprovechando esta misma pregunta.
En esa función que tengo, esta se ejecuta a cada momento ya que le asigno este evento:
AddHandler Dependency.OnChange, AddressOf dependency_Onchange
y en el evento es así:
Private Sub dependency_Onchange(ByVal sender As Object, ByVal e As SqlNotificationEventArgs) Call NotificationCCP() End Sub
Pregunta: como se ejecuta a cada momento, esto afecta el rendimiento en este caso del servidor? ya sea que haya 1, 2, 3 o mas usuarios iniciados que lo utilicen?. intente colocar "If e.Type =SqlNotificationType.Change then" pero ya con este ya no entra porque lo que me devuelve es un e.Type =SqlNotificationType.Subscribe. hay alguna forma que solo se ejecute cuando haya cambios en mi BD?.
Esta misma funcion asi como esta, me sirve para evitar el cierre de la sesión? ya que en ocaciones las variables Session despues de un tiempo me borra información.
Espero me haya explicado.
Saludos.