Giter Site home page Giter Site logo

blazorextensions / signalr Goto Github PK

View Code? Open in Web Editor NEW
211.0 12.0 48.0 1.27 MB

SignalR Core support for Microsoft ASP.NET Core Blazor

License: MIT License

TypeScript 11.83% JavaScript 0.90% C# 73.52% CSS 4.17% HTML 9.58%
signalr signalr-core signalr-client blazor blazor-interop blazor-extensions webassembly web-assembly

signalr's Introduction

Build Package Version NuGet Downloads License

DEPRECATION NOTE: This package is no longer required since Blazor WebAssembly now supports SignalR Client. Users of this package should stop using it and use the official client instead.

Blazor Extensions

Blazor Extensions is a set of packages with the goal of adding useful features to Blazor.

Blazor Extensions SignalR

This package adds a Microsoft ASP.NET Core SignalR client library for Microsoft ASP.NET Blazor.

The package aims to mimic the C# APIs of SignalR Client as much as possible and it is developed by wrapping the TypeScript client by using Blazor's interop capabilities.

For more information about SignalR development, please check SignalR documentation.

Features

This package implements all public features of SignalR Typescript client.

Note: The Streaming APIs are not implemented yet. We will add it soon.

Sample usage

The following snippet shows how to setup the client to send and receive messages using SignalR.

The HubConnectionBuilder needs to get injected, which must be registered:

// in Startup.cs, ConfigureServices()
   services.AddTransient<HubConnectionBuilder>();
// in Component class
[Inject]
private HubConnectionBuilder _hubConnectionBuilder { get; set; }
// in Component Initialization code
var connection = _hubConnectionBuilder // the injected one from above.
        .WithUrl("/myHub", // The hub URL. If the Hub is hosted on the server where the blazor is hosted, you can just use the relative path.
        opt =>
        {
            opt.LogLevel = SignalRLogLevel.Trace; // Client log level
            opt.Transport = HttpTransportType.WebSockets; // Which transport you want to use for this connection
        })
        .Build(); // Build the HubConnection

connection.On("Receive", this.Handle); // Subscribe to messages sent from the Hub to the "Receive" method by passing a handle (Func<object, Task>) to process messages.
await connection.StartAsync(); // Start the connection.

await connection.InvokeAsync("ServerMethod", param1, param2, paramX); // Invoke a method on the server called "ServerMethod" and pass parameters to it. 

var result = await connection.InvokeAsync<MyResult>("ServerMethod", param1, param2, paramX); // Invoke a method on the server called "ServerMethod", pass parameters to it and get the result back.

Contributions and feedback

Please feel free to use the component, open issues, fix bugs or provide feedback.

Contributors

The following people are the maintainers of the Blazor Extensions projects:

signalr's People

Contributors

admiralsnyder avatar attilah avatar catoleantruetschel avatar danielcarmingham avatar dazinator avatar divinci avatar galvesribeiro avatar mitch528 avatar theprateik avatar tpiotrowski avatar wiworowa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

signalr's Issues

Upgrading Blazor WebAssembly to 3.1.0-preview4.19579.2 leads to an error: Could not find 'BlazorExtensions' in 'window'.

Recently I tried to update my blazor wasm project (which uses Blazor.Extensions.SignalR v1.1.0-preview3) to latest 3.1.0-preview4.19579.2 Blazor version.
After updating, an error began to appear in browser console:

Could not find 'BlazorExtensions' in 'window'. Error: Could not find 'BlazorExtensions' in 'window'.
 at http://localhost:7258/_framework/blazor.webassembly.js:1:8937
 at Array.forEach (<anonymous>)
 at p (http://localhost:7258/_framework/blazor.webassembly.js:1:8898)
 at Object.invokeJSFromDotNet (http://localhost:7258/_framework/blazor.webassembly.js:1:9470)
 at _mono_wasm_invoke_js_marshalled (http://localhost:7258/_framework/wasm/mono.js:1:165750)
 at wasm-function[6221]:0x11936a
 at wasm-function[1431]:0x402ee
 at wasm-function[636]:0x147cf
 at wasm-function[636]:0x19ae2
 at wasm-function[4996]:0xeb135

It is probably due to latest changes related to static assets in libraries - as we can see at https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-1/

Support for static assets in libraries when publishing
Standalone Blazor WebAssembly apps now support static assets from Razor class libraries both during development and when publishing. This applies to both standalone Blazor WebAssembly apps and ASP.NET Core hosted apps. Static assets are consumed from referenced libraries using the path prefix: _content/{LIBRARY NAME}/.

There is also PR @ AspNetCore src repo: https://github.com/aspnet/AspNetCore/pull/17353/files
Problem is also reported in several other projects which uses *.js static assets.

Initially I have also tried to update Blazor.Extensions.SignalR to 3.1.0-preview4.19579.2 and the same Could not find 'BlazorExtensions' in 'window' occured when Blazor.Extensions.SignalR.Test.Server started.

I have discovered some differences between old build output and new build output, eg.:

[old - netstandard2.0]

  • there WAS: test\Blazor.Extensions.SignalR.Test.Client\bin\Debug\netstandard2.0\dist\_content\Blazor.Extensions.SignalR.JS
  • there WAS: "jsReferences": [ "_content/Blazor.Extensions.SignalR.JS" ] entry in test\Blazor.Extensions.SignalR.Test.Client\bin\Debug\netstandard2.0\dist\_framework\blazor.boot.json

[new - netstandard2.1]

  • test\Blazor.Extensions.SignalR.Test.Client\bin\Debug\netstandard2.1\dist\_content\Blazor.Extensions.SignalR.JS does NOT exists
  • test\Blazor.Extensions.SignalR.Test.Client\bin\Debug\netstandard2.1\dist\_framework\blazor.boot.json does NOT contain "jsReferences": [ "_content/Blazor.Extensions.SignalR.JS" ] entry

I have forked Blazor.Extensions.SignalR repo and I will try to prepare workaround...

[Question] - Reason for this library?

I am looking to use signalr client in my blazor (client side) app.
My first thought was to add the official signalr.client nuget package:

<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.0.0-preview6.19307.2" />

Then I stumbled accross this project which wraps the typescript version - i'm assuming there must be a reason why the Microsoft.AspNetCore.SignalR.Client package I have referenced above won't work in blazor client applications and why this project exists? Are you able to clarify what the reason is as that will help me decide what to do!

Cheers

Casting JSRuntime.Current to IJSInProcessRuntime

At several places, the current js-runtime is cast to IJSInProcessRuntime. This seems to be ok for the default case, but is this really safe to do with future cases in mind?

My proposal is to add a helper (extension method) that performs this cast, with a workaround, for the case, that the js-runtime is not an in-processes runtime and substitute all occurances of the cast.
This could look like this:

internal static class JSRuntimeExtensions
{
    public static T InvokeSync<T>(
        this IJSRuntime jsRuntime, 
        string identifier, 
        params object[] args)
    {
        if (jsRuntime == null)
            throw new ArgumentNullException(nameof(jsRuntime));

        if(jsRuntime is IJSInProcessRuntime inProcessJsRuntime)
        {
           return inProcessJsRuntime.Invoke<T>(identifier, args);
        }

        return jsRuntime.InvokeAsync<T>(identifier, args)
                                  .ConfigureAwait(false)
                                  .GetAwaiter()
                                  .GetResult();
    }
}

This solution is not ideal either and should be handled with care.

Non-generic overload of the On method?

Any way to call the non-generic On method like the example in the docs?

Example from docs:
connection.On("Receive", this.Handle);

If not, any reason why the non-generic is not implemented? I'm trying to accomplish this:
private void Configure() { HubConnection.On("notify", this.OnConnectedToAPI); } public void OnConnectedToAPI() { Console.WriteLine("============================"); }

Thanks in advance!

InvalidOperationException: JSRuntime must be set up correctly and must be an instance of JSRuntimeBase to use DotNetObjectRef.

I have created a blazor server app in Visual studio preview 2019 and Blazor.Extensions.SignalR (0.2.0). Getting an error when I am trying to listen the signalR message and reloading the table.Do I missed any namespace or something else?

Here my code is,
ViewLog.razor file
@page "/ViewLog"
@using Telerik.Blazor;
@using Telerik.Blazor.Components.Grid;
@using Microsoft.WindowsAzure.Storage;
@using Microsoft.WindowsAzure.Storage.Table;
@using System.Threading.Tasks;
@using WcomLogViewerBlazor.Models;
@using Microsoft.Azure.Documents;
@using Blazor.Extensions;
@using Microsoft.AspNetCore.SignalR;
@using Microsoft.Extensions.DependencyInjection;
@using System.Net.Http;
@using Microsoft.JSInterop;
@using Newtonsoft.Json;

[Inject] private HubConnectionBuilder _hubConnectionBuilder { get; set; }
private HubConnection connection;
private IJSRuntime _runtime;
// Listen SignalR messages and update table
protected override async Task OnInitAsync()
{
    var BaseUrl = "http://localhost:7071/api/SignalRInfo";
    var resonse = await client.GetStringAsync(BaseUrl);
    var responseInfo = JsonConvert.DeserializeObject<Models.ConnectionInfo>(resonse as string);
    var URL = responseInfo.URL;
    var token = responseInfo.AccessToken;
    this.connection = this._hubConnectionBuilder
        .WithUrl(URL,
        opt =>
    {
        opt.LogLevel = SignalRLogLevel.Trace; // Client log level
    opt.Transport = HttpTransportType.WebSockets; // Which transport you want to use for this connection
}) .Build();
    connection.On<string>("TableUpdated", this.OnBroadcastMessage);
       await this.connection.StartAsync();
}

startup.cs

        services.AddTelerikBlazor();
        services.AddTransient<HubConnectionBuilder>();
        services.AddSignalR();

Project.csproj file








HubConnectionBuilder throws NullReferenceException

Hi,

I try incorporating this extension to a blazor app but I encounter an error when establishing a connection.
Here's what I've done which is based on the usage in the README

  • Define endpoints for the hub endpoints.MapHub<TodoHub>("/todoHub")
  • Added services.AddTransient<HubConnectionBuilder>(); in Startup.cs
  • Added
[Inject]
 private HubConnectionBuilder _hubConnectionBuilder { get; set; }

protected override async Task OnInitializedAsync()
 {
        HubConnection connection = _hubConnectionBuilder.WithUrl("/todoHub",
            opt =>
            {
               opt.LogLevel = SignalRLogLevel.Trace;
               opt.Transport = HttpTransportType.WebSockets;
           })
        .Build();
        connection.On<string, string>("ReceiveMessage", this.ProcessMessage);
        await connection.StartAsync();
  }

With following the steps above what I expect is it will run smoothly but rather it throws NullReferenceException.

The whole stacktrace is https://gist.github.com/jhefreyzz/eb6194d478e7b43564eabada4e454a07

Uses the latest release from ASP.NET core

Off() method not exposed in HubConnection

The Off() method is implemented in the HubConnectionManager but not exposed trough HubConnection like the On<T>() Method

How do I unregister a function then?

Thanks!

Broken on 3.0.0-preview6

Nuget Packet is Broken on 3.0.0-preview6.
Sample is broken as well.

2>Fatal error in IL Linker 2> 2>Unhandled Exception: Mono.Linker.MarkException: Error processing method: 'System.Threading.Tasks.Task Blazor.Extensions.HubConnection/<>c__DisplayClass30_0`10::<On>b__0(System.String[])' in assembly: 'Blazor.Extensions.SignalR.dll' ---> Mono.Cecil.ResolutionException: Failed to resolve !!0 Microsoft.JSInterop.Json::Deserialize(System.String) 2> at Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference) 2> at Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference) 2> at Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction) 2> at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body) 2> at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method) 2> at Mono.Linker.Steps.MarkStep.ProcessQueue() 2> --- End of inner exception stack trace --- 2> at Mono.Linker.Steps.MarkStep.ProcessQueue() 2> at Mono.Linker.Steps.MarkStep.ProcessPrimaryQueue() 2> at Mono.Linker.Steps.MarkStep.Process() 2> at Mono.Linker.Steps.MarkStep.Process(LinkContext context) 2> at Mono.Linker.Pipeline.ProcessStep(LinkContext context, IStep step) 2> at Mono.Linker.Pipeline.Process(LinkContext context) 2> at Mono.Linker.Driver.Run(ILogger customLogger) 2> at Mono.Linker.Driver.Execute(String[] args, ILogger customLogger) 2> at Mono.Linker.Driver.Main(String[] args)

Update to Blazor 0.9.0

Blazor reached version 0.9.0, SignalR should upgrade too.
Potentially some dependencies like Blazor.Extensions.Logging will need to be upgraded to 0.9.0 first.

HubConnectionBuilder initialization doesn't seem to be called.

This is the error i get when trying to build the connection:
(preview 5, server-side blazor.)

Microsoft.JSInterop.JSException: "Could not find 'BlazorExtensions' in 'window'.
Error: Could not find 'BlazorExtensions' in 'window'.
at Anonymous function (https://localhost:5001/_framework/blazor.server.js:8:20872)
at Array.prototype.forEach (native code)
at d (https://localhost:5001/_framework/blazor.server.js:8:20823)
at Anonymous function (https://localhost:5001/_framework/blazor.server.js:8:21427)
at Promise (native code)
at e.jsCallDispatcher.beginInvokeJSFromDotNet (https://localhost:5001/_framework/blazor.server.js:8:21397)
at Anonymous function (https://localhost:5001/_framework/blazor.server.js:1:16644)
at Array.prototype.forEach (native code)
at e.prototype.invokeClientMethod (https://localhost:5001/_framework/blazor.server.js:1:16619)
at e.prototype.processIncomingData (https://localhost:5001/_framework/blazor.server.js:1:14619)"

Cannot deserialize decimal with MessagePack and System.Text.Json

Blazor.Extensions.SignalR cannot deserialize decimals using Blazor preview 9 (and System.Text.Json).

To reproduce, just add a decimal to the DemoData class in the test project and enable MessagePack:
In ChatComponent.cs add: opt.EnableMessagePack = true;
In (server) Startup.cs uncomment: .AddMessagePackProtocol();

Any ideas on how to fix this problem? I suspect it's because MessagePack and System.Text.Json are currently incompatible. Possibly related System.Text.Json bug.

A possible fix is to use switch to Newtonsoft instead of the new default System.Text.Json. Previous versions of Blazor.Extensions.SignalR and Blazor 0.9.0 worked fine when used with Newtonsoft as Json serializer. Any way we can make the extension method AddNewtonsoftJsonProtocol work again? Used on
.HubConnectionBuilder(JSRuntimeCurrent).WithUrl("/chathub", options).AddNewtonsoftJsonProtocol();

Exception:

blazor.webassembly.js:1 Uncaught (in promise) Error: System.Text.Json.JsonException: The JSON value could not be converted to System.Decimal. Path: $.Dec | LineNumber: 0 | BytePositionInLine: 42. ---> System.InvalidOperationException: Cannot get the value of a token type 'String' as a number.
  at System.Text.Json.Utf8JsonReader.TryGetDecimal (System.Decimal& value) <0x25a5d98 + 0x0002c> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.Utf8JsonReader.GetDecimal () <0x25a5cc0 + 0x0000a> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.Serialization.Converters.JsonConverterDecimal.Read (System.Text.Json.Utf8JsonReader& reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) <0x25a5c08 + 0x00004> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.JsonPropertyInfoNotNullable`4[TClass,TDeclaredProperty,TRuntimeProperty,TConverter].OnRead (System.Text.Json.JsonTokenType tokenType, System.Text.Json.ReadStack& state, System.Text.Json.Utf8JsonReader& reader) <0x25a59d0 + 0x00070> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.JsonPropertyInfo.Read (System.Text.Json.JsonTokenType tokenType, System.Text.Json.ReadStack& state, System.Text.Json.Utf8JsonReader& reader) <0x20b7938 + 0x00098> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.JsonSerializer.HandleValue (System.Text.Json.JsonTokenType tokenType, System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& state) <0x20b70c0 + 0x000d0> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.JsonSerializer.ReadCore (System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& readStack) <0x20b3ee8 + 0x000a0> in <81e9245ca982431695a55cc67ffb3b86>:0 
   --- End of inner exception stack trace ---
  at System.Text.Json.ThrowHelper.ReThrowWithPath (System.Text.Json.ReadStack& readStack, System.Text.Json.Utf8JsonReader& reader, System.Exception ex) <0x25ef9d0 + 0x00028> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.JsonSerializer.ReadCore (System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader, System.Text.Json.ReadStack& readStack) <0x20b3ee8 + 0x00340> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.JsonSerializer.ReadCore (System.Type returnType, System.Text.Json.JsonSerializerOptions options, System.Text.Json.Utf8JsonReader& reader) <0x20a9df0 + 0x0003e> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.JsonSerializer.ParseCore (System.String json, System.Type returnType, System.Text.Json.JsonSerializerOptions options) <0x20a5b00 + 0x00086> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at System.Text.Json.JsonSerializer.Deserialize[TValue] (System.String json, System.Text.Json.JsonSerializerOptions options) <0x2591390 + 0x00022> in <81e9245ca982431695a55cc67ffb3b86>:0 
  at Blazor.Extensions.HubConnection+<>c__DisplayClass30_0`10[TResult1,TResult2,TResult3,TResult4,TResult5,TResult6,TResult7,TResult8,TResult9,TResult10].<On>b__0 (System.String[] payloads) <0x25910d0 + 0x000a8> in <c55a512ad88d4b5691739ffb720e5e8d>:0 
  at (wrapper delegate-invoke) System.Func`2[System.String[],System.Threading.Tasks.Task].invoke_TResult_T(string[])
  at Blazor.Extensions.HubMethodCallback.On (System.String[] payloads) <0x2505058 + 0x00014> in <c55a512ad88d4b5691739ffb720e5e8d>:0 
  at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x1c128d0 + 0x000d2> in <b455df9113dd49c5bfed215a721aae19>:0 
--- End of stack trace from previous location where exception was thrown ---

  at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously (Microsoft.JSInterop.JSRuntime jsRuntime, Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo& callInfo, Microsoft.JSInterop.Infrastructure.IDotNetObjectReference objectReference, System.String argsJson) <0x21d7068 + 0x0018a> in <b57783c7fafa47088562351a82800d2f>:0 
  at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet (Microsoft.JSInterop.JSRuntime jsRuntime, Microsoft.JSInterop.Infrastructure.DotNetInvocationInfo invocationInfo, System.String argsJson) <0x2246838 + 0x000ba> in <b57783c7fafa47088562351a82800d2f>:0 
    at Object.endInvokeDotNetFromJS (http://localhost:61448/_framework/blazor.webassembly.js:1:7164)
    at Object.invokeJSFromDotNet (http://localhost:61448/_framework/blazor.webassembly.js:1:6790)
    at _mono_wasm_invoke_js_marshalled (http://localhost:61448/_framework/wasm/mono.js:1:176158)
    at wasm-function[6322]:0x129810
    at wasm-function[1962]:0x6063e
    at wasm-function[565]:0x12891
    at wasm-function[565]:0x12eca
    at wasm-function[565]:0x12c35
    at wasm-function[565]:0x12c35
    at wasm-function[565]:0x12eca

Implement StateChanged event and other events

Right now we only have OnClose, all events would be great:

  • Received: Raised when any data is received on the connection. Provides the received data.
  • ConnectionSlow: Raised when the client detects a slow or frequently dropping connection.
  • Reconnecting: Raised when the underlying transport begins reconnecting.
  • Reconnected: Raised when the underlying transport has reconnected.
  • StateChanged: Raised when the connection state changes. Provides the old state and the new state. For information about connection state values see ConnectionState Enumeration.
  • Closed: Raised when the connection has disconnected.

See the connection lifetime events in the the ASP.NET SignalR Hubs API Guide - .NET Client (C#)

Serialization Issue / Configuration

There is a serialization issue. Looks like json serializer configuration. I'm not able to receive deserialized entity as a message. All fields have default values. (case sensitive serialization?)

Workaround: Serialize as string in server side, send the message as string, and deserialize as entity later. But I don't want todo this.

Now I'm using Blazor.Extensions.SignalR 0.4.0 but I noticed this behavior since preview 7.

Upgrading to .NET Standard 2.1 in the Blazor client-side project causes a runtime error

Upon starting the project, I get the following error. It appears to be looking for a dist folder, which is not present when building against .NET Standard 2.1 (but is there for version 2.0):

System.IO.DirectoryNotFoundException: /home/adam/Source/Kartel/Kartel.Web/bin/Debug/netstandard2.1/dist/
  at at Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(String root, ExclusionFilters filters)
  at at Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(String root)
  at at Microsoft.AspNetCore.Builder.BlazorHostingApplicationBuilderExtensions.UseClientSideBlazorFiles(IApplicationBuilder app, String clientAssemblyFilePath)
  at at Microsoft.AspNetCore.Builder.BlazorHostingApplicationBuilderExtensions.UseClientSideBlazorFiles[TClientApp](IApplicationBuilder app)
  at Kartel.Api.Startup.Configure(IApplicationBuilder app, IWebHostEnvironment env) in /home/adam/Source/Kartel/Kartel.Api/Startup.cs:74
  at at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
  at at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
  at at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
  at at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)
  at at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
  at at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
  at at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
  at at Microsoft.AspNetCore.Hosting.WebHost.BuildApplication()
  at at Microsoft.AspNetCore.Hosting.WebHost.StartAsync(CancellationToken cancellationToken)
  at at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage)
  at at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage)
  at at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
  at at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
  at Kartel.Api.Program.Main(String[] args) in /home/adam/Source/Kartel/Kartel.Api/Program.cs:11

Don't work for preview 7

Unhandled exception. Mono.Linker.MarkException: Error processing method: 'System.Threading.Tasks.Task Blazor.Extensions.HubConnection/<>c__DisplayClass30_0`10::b__0(System.String[])' in assembly: 'Blazor.Extensions.SignalR.dll'
Mono.Cecil.ResolutionException: Failed to resolve !!0 System.Text.Json.Serialization.JsonSerializer::Parse(System.String,System.Text.Json.Serialization.JsonSerializerOptions)
at Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference)
at Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference)
at Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction)
at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body)
at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method)
at Mono.Linker.Steps.MarkStep.ProcessQueue()

JsRuntime on Server side

I get this error using server side: InvalidOperationException: JSRuntime must be set up correctly and must be an instance of JSRuntimeBase to use DotNetObjectRef. I can't seem to figure out how to get around it,

Perhaps related to this?
dotnet/aspnetcore#11159

Follwing sample with latest preview

Attempt by method 'Blazor.Extensions.HubConnection..ctor(Blazor.Extensions.HttpConnectionOptions)' to access method 'Microsoft.JSInterop.JSRuntime.get_Current()' failed.

Simple example test fails with the above.

Server Hub receives ValueTuple with default values

I'm having issues with sending a ValueTuple to the server as the parameter arrives at the ServerHub with default values apparently. I am not sure if this is a BlazorExtensions or a SignalR issue and I was unable to find any issues related to ValueTuple on either GitHubs... Perhaps posting here will shed some light on this matter.

On the client I'm using the following method:

public async Task<UserBaseModel?> LoginUserWithOpenIdAsync((string LoginToken, string Code) uriParameters)
{
            await this.ConnectToAPITask;
            if (this.ConnectToAPITask.IsCompleted)
            {
                        Console.WriteLine("======================");
                        Console.WriteLine(uriParameters.LoginToken);
                        Console.WriteLine("======================");
                        UserBaseModel? user = await this.HubConnection.InvokeAsync<UserBaseModel?>("LoginUserWithOpenIdAsync", uriParameters);

                        if (user != null) { } 
            }

            return null;
}

The client prints out to console just fine:
WASM: 7aQ2/1cZvsvZlIbPK26m9T0EGcqPAtAfzoOQ85EoE2s=

And on the server I have the following method:

public async Task<UserBaseModel?> LoginUserWithOpenIdAsync((string LoginToken, string Code) uriParameters)
        {
            Console.WriteLine("======================");
            Console.WriteLine(uriParameters.GetType().ToString());
            if (uriParameters == default(ValueTuple<string, string>))
            {
                Console.WriteLine("Default values");
            }
            Console.WriteLine(uriParameters.LoginToken);
            Console.WriteLine(uriParameters.Code);
            Console.WriteLine("======================");
            ...
}

The server appears to be receiving the default values for the ValueTuple with two empty strings:

======================                                                                                                  System.ValueTuple`2[System.String,System.String]
Default values


======================

If I serialize it to JSON I can bypass the issue, but I'd rather avoid it if possible.

Could this be some sort of limitation on either SignalR or BlazorExtensions? If not, any ideas on what might be wrong?

Sorry for the trouble, thanks in advance!

Byte array as handler arguments and hub handler

When using byte arrays as client handler arguments or as return type of hub handlers, the signal-r ts-client outputs these as TypedArray. When passed back to .Net these have to be deserialized either directly or indirectly, but SimpleJson, seems to have a problem deserializing TypedArrays to .Net arrays.

Preview 2

Hi, first of all thanks for your efforts. Just wanted to know if you are planning to support preview 2 any time soon?

Getting on creating connection after update to 0.1.3

When creating a connection I'm getting a
TypeError: Cannot read property 'LogLevel' of undefined at http://localhost:1234/_content/Blazor.Extensions.SignalR.JS:30:10392

Code:

connection = new HubConnectionBuilder()
    .WithUrl($"{baseUrl}/blazorhub", opt =>
    {
        opt.AccessTokenProvider = () => Task.FromResult(Jwt);
        opt.SkipNegotiation = true;
        opt.Transport = HttpTransportType.WebSockets;
     })
     .AddMessagePackProtocol()
     .Build();

Object of type 'System.Int64' cannot be converted to type 'System.UInt32'

I am using an ASP.NET Server hosting a Blazor application + SignalR server. My browser app communicates to that server via BlazorExtensions/SignalR using MessagePack (but same problem with JSON). When I try to serialize a simple class consisting of an enum and an uint32 field, I get the following errors:

enum: Input string was not in a correct format.
uint32: Object of type 'System.Int64' cannot be converted to type 'System.UInt32'

I am not sure what exactly causes the issues but I think that it can be easily reproduced (or not) if you extend your tests with enum and uint32 fields.

Thank you

Why is this needed?

I'm going to be building a client side blazor app with some SignalR features. I'm curious why I even need this package vs the normal SignalR packages?

I already have Razor components using the C# SignalR package that I'm using with a server side app. Will these components not work on a client side app?

Essentially: Why can't I just use the normal Microsoft SignalR packages when doing client side Blazor? I think this should be added to the readme to make it more clear why this package exists.

Serialization/Deserialization behavior different from SignalR JS/TS client

My use case had me build a hub that only sends data to the client in two methods - one that sends a simple POCO with data (i send it directly, i don't convert it to JSON or serialize it myself) and another that sends an IEnumerable of POCOs (similar to the former, but a different one).

When testing the same hub against a simple JS client, Both are received properly deserialized and "unboxed" - simply the object and the array (as JS interprets it) themselves.

When trying the same with the Blazor client, The single object is received as a SimpleJson.JsonObject class instead while the IEnumerable doesn't arrive and the method callback on the client receives a null object.

Attached is a small repro solution to show the issue - A server running a single SignalR hub with a method for the clients to trigger the two receiving callbacks, A demo JS client and a demo Blazor client - Both with simple button operation to connect and trigger the data callbacks. See the console on both for results.

Thanks!

SignalRTests.zip

.net 3 preview 9 build error

Hi, got this error after updating to preview 9:
11>Unhandled Exception: Mono.Linker.MarkException: Error processing method: 'System.Void Blazor.Extensions.HubConnection::.ctor(Microsoft.JSInterop.IJSRuntime,Blazor.Extensions.HttpConnectionOptions)' in assembly: 'Blazor.Extensions.SignalR.dll' ---> Mono.Cecil.ResolutionException: Failed to resolve Microsoft.JSInterop.DotNetObjectRef`1<!!0> Microsoft.JSInterop.DotNetObjectRef::Create(!!0)
11> at Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference)
11> at Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference)
11> at Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction)
11> at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body)
11> at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method)
11> at Mono.Linker.Steps.MarkStep.ProcessQueue()
11> --- End of inner exception stack trace ---
11> at Mono.Linker.Steps.MarkStep.ProcessQueue()
11> at Mono.Linker.Steps.MarkStep.ProcessPrimaryQueue()
11> at Mono.Linker.Steps.MarkStep.Process()
11> at Mono.Linker.Steps.MarkStep.Process(LinkContext context)
11> at Mono.Linker.Pipeline.ProcessStep(LinkContext context, IStep step)
11> at Mono.Linker.Pipeline.Process(LinkContext context)
11> at Mono.Linker.Driver.Run(ILogger customLogger)
11> at Mono.Linker.Driver.Execute(String[] args, ILogger customLogger)
11> at Mono.Linker.Driver.Main(String[] args)

ConnectionId Required when navigating to SignalR page

Startup from Server:
[code]
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Serialization;
using System.Linq;

namespace BlazorAndSignalR.Server
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson();
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});

        services.AddCors(options => options.AddPolicy("CorsPolicy", builder =>
        {
            builder.AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials()
                .WithOrigins("http://localhost:51742");
        }));
        services.AddSignalR();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseResponseCompression();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBlazorDebugging();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();
        });

        app.UseCors("CorsPolicy");
        app.UseSignalR(routes => routes.MapHub<ChatHub>("/chathub"));
        app.UseHttpsRedirection();
        app.UseBlazor<Client.Startup>();
    }
}

}

[/code]

Hub:
[code]
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace BlazorAndSignalR.Server
{
public class ChatHub : Hub
{
public override Task OnConnectedAsync()
{
if(string.IsNullOrEmpty(Context.ConnectionId))
{
throw new System.Exception(nameof(Context.ConnectionId)); //This code is never hit
}
Clients.All.SendAsync("broadcastMessage", "system", $"{Context.ConnectionId} joined the conversation");
return base.OnConnectedAsync();
}
public void Send(string name, string message)
{
Clients.All.SendAsync("broadcastMessage", name, message);
}

    public override Task OnDisconnectedAsync(System.Exception exception)
    {
        Clients.All.SendAsync("broadcastMessage", "system", $"{Context.ConnectionId} left the conversation");
        return base.OnDisconnectedAsync(exception);
    }
}

}
[/code]

Page:
[code]
@page "/chathub"

@functions { [Inject] IJSRuntime jsRuntime { get; set; }
HubConnection connection;
string Message = "";
IList<string> messages = new List<string>();

protected override async Task OnInitAsync()
{
    connection = new HubConnectionBuilder(jsRuntime).WithUrl("https://localhost:51742/chathub").Build();
    connection.On<string, string>("broadcastMessage", this.OnBroadcastMessage);
    await connection.StartAsync();
}

Task OnBroadcastMessage(string name, string message)
{
    messages.Add(name + " : " + message);
    StateHasChanged();
    return Task.CompletedTask;
}

async Task SendMessage()
{
    await connection.InvokeAsync("Send", "Blazor Client", Message);
    Message = "";
}

}
[/code]

Serialization error using DateTime and Guid.

I am using an ASP.NET Server hosting a Blazor application + SignalR server.
My browser app communicates to that server via BlazorExtensions/SignalR
In the simple classes that I pass it works fine for integers, strings and bytearrays, but not for Guid and DateTime.

If I send the DateTime as a long it works, but for a DateTime I get the following error:
Uncaught (in promise) Error: System.FormatException: String was not recognized as a valid DateTime.
at System.DateTimeParse.Parse (System.ReadOnlySpan`1[T] s, System.Globalization.DateTimeFormatInfo dtfi, System.Globalization.DateTimeStyles styles) <0x23ed4a0 + 0x00074> in <6d03508d2e754cd29d153e0b362bc7fa>:0
at System.DateTime.Parse (System.String s, System.IFormatProvider provider, System.Globalization.DateTimeStyles styles) <0x23ed320 + 0x00038> in <6d03508d2e754cd29d153e0b362bc7fa>:0
at SimpleJson.PocoJsonSerializerStrategy.DeserializeObject (System.Object value, System.Type type) <0x1e54210 + 0x001b2> in <8f8c03446dbf45f5bbcb1e109a064f6e>:0
at SimpleJson.PocoJsonSerializerStrategy.DeserializeObject (System.Object value, System.Type type) <0x1e54210 + 0x00862> in <8f8c03446dbf45f5bbcb1e109a064f6e>:0
at SimpleJson.SimpleJson.DeserializeObject (System.String json, System.Type type, SimpleJson.IJsonSerializerStrategy jsonSerializerStrategy) <0x1e51c68 + 0x00068> in <8f8c03446dbf45f5bbcb1e109a064f6e>:0
at SimpleJson.SimpleJson.DeserializeObject[T] (System.String json) <0x24aae90 + 0x0000a> in <8f8c03446dbf45f5bbcb1e109a064f6e>:0
at Microsoft.JSInterop.Json.Deserialize[T] (System.String json) <0x24aae58 + 0x00004> in <8f8c03446dbf45f5bbcb1e109a064f6e>:0

Support automatic reconnects and State on HubConnection

The Javascript ASP.NET Core SignalR client now support automatic reconnects, which would be super useful to have.

Stuff needed to be implemented:

  • withAutomaticReconnect() function on HubConnectionBuilder
  • onreconnecting event on HubConnection
  • state property on HubConnection

If this sounds too big, just having the State property on HubConnection would be extremely helpful so we can detect if a (re)connection succeeded or not.

Thanks for all the work you're putting in! :)

IL Linker fails to process package

Running netcore 3.0.100-preview5-011568:

1>Fatal error in IL Linker
1>
1>Unhandled Exception: Mono.Linker.MarkException: Error processing method: 'System.Void Microsoft.AspNetCore.Blazor.Services.WebAssemblyUriHelper::NotifyLocationChanged(System.String)' in assembly: 'Microsoft.AspNetCore.Blazor.dll' ---> Mono.Cecil.ResolutionException: Failed to resolve System.Void Microsoft.AspNetCore.Components.UriHelperBase::TriggerOnLocationChanged()
1>   at Mono.Linker.Steps.MarkStep.HandleUnresolvedMethod(MethodReference reference)
1>   at Mono.Linker.Steps.MarkStep.MarkMethod(MethodReference reference)
1>   at Mono.Linker.Steps.MarkStep.MarkInstruction(Instruction instruction)
1>   at Mono.Linker.Steps.MarkStep.MarkMethodBody(MethodBody body)
1>   at Mono.Linker.Steps.MarkStep.ProcessMethod(MethodDefinition method)
1>   at Mono.Linker.Steps.MarkStep.ProcessQueue()
1>   --- End of inner exception stack trace ---
1>   at Mono.Linker.Steps.MarkStep.ProcessQueue()
1>   at Mono.Linker.Steps.MarkStep.ProcessPrimaryQueue()
1>   at Mono.Linker.Steps.MarkStep.Process()
1>   at Mono.Linker.Steps.MarkStep.Process(LinkContext context)
1>   at Mono.Linker.Pipeline.ProcessStep(LinkContext context, IStep step)
1>   at Mono.Linker.Pipeline.Process(LinkContext context)
1>   at Mono.Linker.Driver.Run(ILogger customLogger)
1>   at Mono.Linker.Driver.Execute(String[] args, ILogger customLogger)
1>   at Mono.Linker.Driver.Main(String[] args)

Object not properly deserialized due to case-sensitivity

Hi!

First of all, thanks for the library! It's great to have possibility to use SignalR in Blazor with C#.

I have an issue with deserialization of an object. There's an example code attached.

On client side I changed the Index component to subscribe to a hub and added a button to poke a controller on server side that sends an object through the hub.

Problem is, that all strings are empty in the object received in the client in method registered through .On<> (OnPostReceived). The contents of the received message is logged to console:

image

When I looked at the packets through Wireshark they seemed to contain sensible data.

It's also possible that I'm doing something very wrong.

I'm using strongly-typed hub on the server, but I don't think it should matter.

BlazorSignalR.zip

Serverside example

Nice work! But is there a way to use this extension with serverside blazor?
I tried to follow this guide https://github.com/Suchiman/BlazorDualMode to switch between clientside and serverside however when I try serverside, the page hangs during load without a good error message.

Build() just.. hangs.

I'm trying to recreate https://youtu.be/Yb-N0TmEq_Y?t=2275 and I have no clue why, but it just hangs exactly here. I set a breakpoint on that line and on line 32, hit continue, and nothing happens, no console output in the browser, and the nav menu (when I want to go to Counter or others) are not responsive.

Debugger stepping into doesn't work, and I'm not a blazor pro and not a web dev pro, so I'm kinda stuck. I'm using VS2019 preview with asp.net 3 and RazorComponents. All of that is preview heh.

Missing method exception on Build

dotnet 3.0.100-preview6-012264
BlazorExtensions 0.1.9
im using serverside blazor
Im getting this error on init
var connection = _hubConnectionBuilder .WithUrl("/hubs/ChatHub", opt => { opt.LogLevel = SignalRLogLevel.Trace; opt.Transport = HttpTransportType.WebSockets; }).Build();

System.MissingMethodException: Method not found: 'Void Microsoft.JSInterop.DotNetObjectRef..ctor(System.Object)'. at Blazor.Extensions.HubConnection..ctor(IJSRuntime runtime, HttpConnectionOptions options) at Blazor.Extensions.HubConnectionBuilder.Build()

examples needed

I want to use signalr with wpf but there's no examples...
I want to use signalr as a frontend, wpf as a backend...

Implement token factory

SignalR allow you to pass a function to the connection options that return an access token.

We must enable that in the C# side as well. Today we only allow people to pass in the fixed access token.

Can't serialize poco class

I'm sening a POCO with a SignalR hub then, it gets sent to my subscribed client, but the data is lost.

The data I'm sending

public class WorkerOrderViewDto
    {
        public int Id { get; set; }
        public string UserName { get; set; } = string.Empty;
        public ICollection<SandwichDto> Sandwiches { get; set; } = new List<SandwichDto>();
        public OrderState State { get; set; }
    }
public enum OrderState
    {
        OrderPlaced,
        InTheOven,
        ToBeDelivered,
        Delivered,
    }

The Hub

public class WorkerViewOrderHub : Hub<IWorkerViewOrderClient>
    {
    }

    public interface IWorkerViewOrderClient
    {
        Task ReceiveOrderAddedAsync(WorkerOrderViewDto orders);
    }

Sending the data

private readonly IHubContext<WorkerViewOrderHub, IWorkerViewOrderClient> _workerViewHub;
public async Task<ActionResult> AddOrderAsync([FromBody] AddOrderDto addOrderDto)
        {
            var userId = _userManager.GetUserId(HttpContext.User) ?? throw new InvalidCommandException();
            addOrderDto.UserId = userId;
            addOrderDto.CustomerId = userId;

            var result = await _serverOrderService.AddOrderAsync(addOrderDto);

            var orderView = (await _serverOrderService.GetPendingOrdersForWorkerAsync()).SingleOrDefault(o => o.Id == result);

            await _workerViewHub.Clients.All.ReceiveOrderAddedAsync(orderView);

            return new OkResult();
        }

SignalR Client

_connection.On<WorkerOrderViewDto>(HubNames.WorkerViewOrderHubNames.ReceiveOrderAddedAsync, OnOrdersModifiedAsync);

            Task OnOrdersModifiedAsync(WorkerOrderViewDto order)
            {
                Orders.Add(order);

                OrdersChanged?.Invoke();

                return Task.CompletedTask;
            }

Chrom debug inspection of the serialized data:
https://imgur.com/gallery/m37ptwF

The client connects, gets the message, OnOrdersMidifiedAsync gets called, but the data is not serialized properly. Any idea what I'm doing wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.