Calling async methods in OnOpen

40 views
Skip to first unread message

Maarten88

unread,
Jun 3, 2015, 12:08:11 PM6/3/15
to xsocke...@googlegroups.com
Hi,

We are building an app using XSockets where we work with data from a backend that requires async calls for everything. 

I have added several backend calls in the OnOpen method to initialize the Controller. But this has caused lots of problems and instability, 
because OnOpen is not async and calling .Wait() or .Result gives all sorts of deadlocks. (btw Errorhandling in XSockets is yet another issue)

After lots of tweaking with AsyncHelper functions copied from StackOverflow (that I do not really understand) it is "mostly" working, but it 
feels like a hack, and the OnOpen now sometimes breaks on seemingly unrelated changes.

I have tried using the OnOpen event and making it "async void" (like it is possible in Windows UI controls) but XSockets does not seem to support this.

Is there any advise what I can do about this? I think what I need is an OnOpenAsync (and OnClose, etc) that runs in an async context like all public 
methods in the Controller. Or is there another way to stabilize this code?

-- Maarten

Ulf Björklund

unread,
Jun 3, 2015, 12:40:39 PM6/3/15
to xsocke...@googlegroups.com
Hi Maarten

Some background... 
The C# client targets .NET 4.0 since it was built in the beginning of XSockets. A client in 4.5+ would have been using async and await.
Another thing about the client is that it uses WebSockets as communication protocol. If the client was written today the protocol would have been something else, but once again.. The client was written when we only had WebSockets as communication protocol.

A good thing though is that all clients are open source on github (https://github.com/XSockets/XSockets.Clients)! So tweaking the client to fit specific needs would probably be easy to do. More easy than struggling with the 4.0 client and AsyncHelpers.
We often write custom protocol and custom clients for our customers, especially in the IoT area since many "devices/things" does not talk websockets and they need custom protocol and clients.
I will be happy to take a quick look at what you need. Can you provide some details about what you want... Just so that I do not waste time on something that you are not interested in.

Regards
Uffe

Maarten88

unread,
Jun 3, 2015, 5:57:37 PM6/3/15
to xsocke...@googlegroups.com
I'm sorry, I see that my question was unclear: this is about the server side part of the system. The problematic OnOpened method is in a serverside Controller that is subclassed from the abstract XSockets.Core.XSocket.XSocketController baseclass. The OnOpened method takes the Identity of the user and then connect to a Microsoft Orleans based backend, keeping references to Actor objects and subscribing additional interfaces on the XSocketController to events. This gives us two-way dataflows where clients receive updates nearly instantly if the underlying data changes.

Ulf Björklund

unread,
Jun 4, 2015, 1:02:24 AM6/4/15
to xsocke...@googlegroups.com
Hi Maarten

When reading your question again it is obvious that you talk about the backend. I just assumed that you were talking about the C# client since that is usually the question.

Anyway, I think the idea with Orleans is very interesting. I have not used Orleans myself (yet), but I understand the concept.
I am sure that I can help you achieve what you want.
Can you share some code to show me what you have created?
If you do not want to post it in public you might be able to send it to me at uf...@xsockets.net ?

If needed I am also available for a Skype meeting about this. If so, my Skype handle is "codeplanner"

Regards
Uffe

Maarten88

unread,
Jun 4, 2015, 3:44:51 AM6/4/15
to xsocke...@googlegroups.com
To give an idea, I'll copy the start of my current OnOpened method:

        public override void OnOpened()
        {
            base.OnOpened();

            // On opening the socket connection:
            // - We subscribe to changes in our person grain in orleans, so we can easily publish these to the client
            if (this.ConnectionContext.User.Identity is ClaimsIdentity && this.ConnectionContext.User.Identity.IsAuthenticated)
            {
                var identity = this.ConnectionContext.User.Identity as ClaimsIdentity;
                
                var cid = identity.FindFirstValue("client");
                if (!String.IsNullOrWhiteSpace(cid))
                {
                    this.clientId = cid;
                }
                // get the currently impersonated person
                this.clientGrain = ClientGrainFactory.GetGrain(this.clientId);
                
                // set the personGrain and subscribe for changes
                AsyncHelper.RunSync(() => this.SetSubscribedPerson(this.AuthenticatedUserId));
                
                // Checkin with the clientgrain, this retuns possible impersonation
                var impersonatedUserSetting = AsyncHelper.RunSync(() => this.clientGrain.CheckIn(this.ConnectionId.ToString(), this.AuthenticatedUserId));
                if (impersonatedUserSetting.HasValue && impersonatedUserSetting.Value != this.AuthenticatedUserId)
                {
                     AsyncHelper.RunSync(() => this.Impersonate(impersonatedUserSetting.Value)); // will subscribe and set personGrain
                }
            }
        }


As you see, there's a lot of RunSync() methods in there that call into async methods.

Another relevant line is this one:
public class SocketApiController : XSocketController, IPersonObserver, IClientSettingsObserver
{
   ...


Our XSocketController also implements observer methods that receive events from Orleans. Of course, this creates lots of opportunities for deadlocks: controller calls grain, grain publishes event, calls back into controller (where initialization is still in progress), initialization calls next method -> deadlock. I need to be quite carefull how data flows.

A big question for me is what kind of guarantees does XSockets provide wrt threads in Controller methods? Is it possible that multiple methods in the same controller are running at the same time, on different threads? Do I need to implement my own locking If I want to avoid this? Can I use .ConfigureAwait(false)? (this seems to cause problems).

Anyway: my original question was how can I get rid of those ugly RunSync methods... One thing I can think of is moving all code from OnOpened into an async Task EnsureInitialized() method and calling that before every normal public method in the Controller. That would probably solve it.


Reply all
Reply to author
Forward
0 new messages