Code-Sharp / WampSharp

A C# implementation of WAMP (The Web Application Messaging Protocol)
http://wampsharp.net
Other
385 stars 83 forks source link

Error in Blazor WebAssembly #322

Closed viniwrubleski closed 3 years ago

viniwrubleski commented 3 years ago

Hi, I am trying to use the library with in a project in Blazor WebAssembly with a ASP.NET Core API. I modified the Weather Forecast example in the blazor demo, and it is working:

protected override async Task OnInitializedAsync()
{
    var serverAddress = "ws://127.0.0.1:5000/ws";
    var factory = new DefaultWampChannelFactory();
    var channel = factory.CreateJsonChannel(serverAddress, "realm1");
    await channel.Open().ConfigureAwait(false);

    var proxy = channel.RealmProxy.Services.GetCalleeProxy<IWeatherForecastService>();
    forecasts = await proxy.Get();
}

But, if the server goes down the whole APP stops working because of this exception:

Unhandled Exception:
blazor.webassembly.js:1 System.Threading.SynchronizationLockException: Cannot wait on monitors on this runtime.
    at (wrapper managed-to-native) System.Threading.Monitor.Monitor_wait(object,int)
    at System.Threading.Monitor.ObjWait (System.Boolean exitContext, System.Int32 millisecondsTimeout, System.Object obj) <0x39f9160 + 0x00046> in <filename unknown>:0 
    at System.Threading.Monitor.Wait (System.Object obj, System.Int32 millisecondsTimeout, System.Boolean exitContext) <0x39f9080 + 0x00022> in <filename unknown>:0 
    at System.Threading.Monitor.Wait (System.Object obj, System.Int32 millisecondsTimeout) <0x39f8fb8 + 0x0000a> in <filename unknown>:0 
    at System.Threading.ManualResetEventSlim.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x39e5a30 + 0x001be> in <filename unknown>:0 
    at System.Threading.Tasks.Task.SpinThenBlockingWait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x39e3e30 + 0x00072> in <filename unknown>:0 
    at System.Threading.Tasks.Task.InternalWait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x39e3820 + 0x000ca> in <filename unknown>:0 
    at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x39e3548 + 0x00036> in <filename unknown>:0 
    at System.Threading.Tasks.Task.Wait () <0x39e3378 + 0x00018> in <filename unknown>:0 
    at WampSharp.Core.Listener.AsyncWampConnection`1[TMessage].System.IDisposable.Dispose () [0x0001a] in D:\a\WampSharp\WampSharp\src\netstandard\WampSharp\Core\Listener\Connections\AsyncConnection\AsyncWampConnection.cs:90
    at WampSharp.Core.Listener.ReviveClientConnection`1[TMessage].DestroyConnection () [0x0005c] in D:\a\WampSharp\WampSharp\src\netstandard\WampSharp\Core\Listener\Connections\ReviveClientConnection.cs:62 
    at WampSharp.Core.Listener.ReviveClientConnection`1[TMessage].OnConnectionClosed (System.Object sender, System.EventArgs e) [0x00000] in D:\a\WampSharp\WampSharp\src\netstandard\WampSharp\Core\Listener\Connections\ReviveClientConnection.cs:50 
    at WampSharp.Core.Listener.AsyncWampConnection`1[TMessage].RaiseConnectionClosed () [0x00010] in D:\a\WampSharp\WampSharp\src\netstandard\WampSharp\Core\Listener\Connections\AsyncConnection\AsyncWampConnection.cs:76 
    at WampSharp.WebSockets.WebSocketWrapperConnection`2[TMessage,TRaw].RunAsync () [0x001bc] in D:\a\WampSharp\WampSharp\src\netstandard\Extensions\WampSharp.WebSockets\WebSockets\WebSocketWrapperConnection.cs:137 
    at WampSharp.WebSockets.WebSocketWrapperConnection`2[TMessage,TRaw].InnerConnect () [0x0009d] in D:\a\WampSharp\WampSharp\src\netstandard\Extensions\WampSharp.WebSockets\WebSockets\WebSocketWrapperConnection.cs:61
    at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_1 (System.Object state) <0x3a06e68 + 0x0000c> in <filename unknown>:0 
    at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x3a06e18 + 0x00022> in <filename unknown>:0 
    at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x2b63270 + 0x00100> in <filename unknown>:0 
    at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x2b5fc08 + 0x00010> in <filename unknown>:0
    at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x3a06da8 + 0x00038> in <filename unknown>:0 
    at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x353d0b0 + 0x00102> in <filename unknown>:0 
    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x3534c48 + 0x00000> in <filename unknown>:0
darkl commented 3 years ago

Wow this is very cool! Maybe you can set up a GitHub repository with your code so I don't need to set it up myself and then I can try troubleshooting this?

Elad

viniwrubleski commented 3 years ago

Sure, I put the code here: https://github.com/viniwrubleski/WampBlazor

darkl commented 3 years ago

Try 21.0.0-blazor-23 from the GitHub packages. I'll keep updating this branch with adjustments for running WampSharp on Blazor.

viniwrubleski commented 3 years ago

Nice, it seems to be working now. The reconnector is working too.

protected override async Task OnInitializedAsync()
{
    var serverAddress = "ws://127.0.0.1:5000/ws";
    var factory = new DefaultWampChannelFactory();
    var channel = factory.CreateJsonChannel(serverAddress, "realm1");

    Func<Task> connect = async () =>
    {
        await channel.Open().ConfigureAwait(false);

        var proxy = channel.RealmProxy.Services.GetCalleeProxy<IWeatherForecastService>();
        forecasts = await proxy.Get();
        StateHasChanged();
    };

    var reconnector = new WampChannelReconnector(channel, connect);
    reconnector.Start();

    await Task.Yield();
}
darkl commented 3 years ago

Cool! Let's close this for now and please open issues about things that don't work properly on Blazor. I expect there will be some.

Elad

Wuschli commented 3 years ago

Hi there! I wasn't able to find the mentioned package in the GitHub packages list. I got the exact same issues with version 20.1.1 from nuget, so I guess the changes aren't integrated in the release? Would be amazing if you could make blazor work right from nuget :)

Cheers, Lukas

Wuschli commented 3 years ago

Update: I was able to narrow my issue down a bit, so maybe it's a bit different than viniwrubleski's case. Looks like awaiting a channel.Close causes it in my case await _channel.Close("Auth Reconnect", new GoodbyeDetails {Message = "Auth Reconnect"});