CodeFirst - Session Management


(Jens) #1


do you have a small example for the Session Management in a CF server?

I created a static class with a static MemorySessionManager instance and assigned it to the NetworkServer.SessionManager property:

server.NetworkServer.SessionManager = Global.SessionManager;

My SessionManager fires the “SessionCreated” and “SessionDestroyed” when I call Login() and Logout() of the LoginService.
On Login() I put some values to the session …

Session["Username"] = username; 
Session["UserPermission"] = currentUser.UserPermission;

Service1 has the “ServiceRequiresLogin” Attribute.
When I call Service1.DoSomething() after logging in I get a SessionNotFoundException.

What’s missing?

Thank you

(antonk) #2

It should “just work”.

Thre is already a place for this - RemObjects.SDK.Server.SessionManager.GlobalSessionManager

Could you create a testcase?

(Jens) #3

Thank you. The GlobalSessionManager works fine so far.
I found some more Details. The Session-Authentication only works with the BIN Message. Using any other message-type I get a SessionNotFoundException, when I call Service1.DoSomething() after the Login.

The additional messages are registered on the server-side:

        server.NetworkServer.RegisterServerMessage(new RemObjects.SDK.JsonMessage());
        server.NetworkServer.RegisterServerMessage(new RemObjects.SDK.XmlRpcMessage());
        server.NetworkServer.RegisterServerMessage(new RemObjects.SDK.SoapMessage());

A Testcase is attached. (124.5 KB)

(Jens) #4

do you was able to reproduce this issue? Is this a flaw in my code or an issue in the SDK?
Can you suggest a workaround to fix the session-persistence on my side by any chance?

(antonk) #5


To enable session id transfer support for JSON Message you need to set its property SessionIdAsId like

server.NetworkServer.RegisterServerMessage(new RemObjects.SDK.JsonMessage { SessionIdAsId = true });

for both server and client side:

    public ServerAccess()
        if (string.IsNullOrWhiteSpace(_serverUrl))
            throw new System.Exception("ServerURL isn't set! (ServerAccess.ServerUrl = .....) ");
        this._clientChannel = ClientChannel.ChannelMatchingTargetUri(_serverUrl);
        this._message = Message.MessageMatchingTargetUri(_serverUrl);
        if (this._message is JsonMessage)
	        (this._message as JsonMessage).SessionIdAsId = true;

For SOAP message you need to set its SoapMode to SoapMode.RPCLiteral or SoapMode.RPCEncoding

The last one message, XmlRpcMessage, doesn’t support sending SessionID from client to server, so it cannot be used to talk to services that require authentication.


(Jens) #6

Thank you. That works well.
What happens there in the background to my understanding, is that the client-messages insert an ID node in the workload, which is resolved in a session-id on the server side.

I am not sure how this kind of ID-handling would look like for a non-ROSDK client. For example an external PHP JSON client, who only see the “/doc infos” and the “/json API”. Is there any examples or documentation for this?

Would the session-persistence of the login service possibly work “out-of-the-box” with a SuperHttpChannel, without changing the message workload itself? Let’s just stay with JSON and forget SOAP and XMLRPC, for simplicity.

(antonk) #7

Samples below were captured using your testcase:

Login request/response JSON:

--> {"version":"1.1","method":"LoginService.Login","params":{"username":"test","password":"test"},"id":"{c585f77b-5f91-4b87-b1d0-ccca24ef8aa1}"}


--< {"version":"1.1","result":true,"id":"{c585f77b-5f91-4b87-b1d0-ccca24ef8aa1}"}

Method call and 2 responses (one for SessionNotFound exception and one for method call executed after login):

--> {"version":"1.1","method":"Service1.DoSomething","params":{"someValue":"11"},"id":"{c585f77b-5f91-4b87-b1d0- ccca24ef8aa1}"}


--< {"version":"1.1","error":{"name":"JsonRPCError","code":"1","message":"Session could not be found."},"id":"{c585f77b-5f91-4b87-b1d0-ccca24ef8aa1}"}

--< {"version":"1.1","result":"11","id":"{c585f77b-5f91-4b87-b1d0-ccca24ef8aa1}"}

The easiest way to find out what server expects and what it will it send back is to intercept the traffic between server and client. I used Fiddler and set up the client channel to use Fiddler as a proxy server:

  var channel = this._clientChannel as IpHttpClientChannel;
  channel.ProxySettings.ProxyHost = "";
  channel.ProxySettings.ProxyPort = 8888;
  channel.ProxySettings.UseProxy = true;

I doubt that you’d really want to implement SuperHttp by yourself for a non-RO platform. And for RO SDK client <–> RO SDK Server communications there is no reason to use other message format than the Binary one.