通过 Azure SignalR 连接 .net6 Web 服务和 .net6 wpf 应用程序

发布于 2025-01-20 04:22:39 字数 2963 浏览 0 评论 0原文

我正在 Azure 上运行一个 Web 服务,它连接到 SignalR,如下所示:

我的 Hub 类:

public class ChangeRequest : Hub
{
    protected IHubContext<ChangeRequest> _context;

    public ChangeRequest(IHubContext<ChangeRequest> context) => _context = context;
    public Task? Send(Guid id) =>
        _context.Clients?.All?.SendAsync("SendMessage", id);
}

我的 Programm.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<CPLopsEntities>(options => options.UseSqlServer(@"Server=tcp:noris.database.windows.net,1433;Initial Catalog=CPLopsTest;Persist Security Info=False;User ID=user;Password=!Pw12345;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"));
builder.Services.AddTransient<ChangeRequest>();

builder.Services.AddSignalR().AddAzureSignalR("Endpoint=https://xxxxxxx.service.signalr.net;AccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;Version=1.0;");

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.UseAzureSignalR(r => r.MapHub<ChangeRequest>("/com"));

using (var scope = app.Services.CreateScope())
    scope.ServiceProvider.GetRequiredService<CPLopsEntities>().Database.Migrate();

app.Run();

当通过调用 Web 服务添加新条目时,我调用 _hub.Send()

private readonly CPLopsEntities _context;
private readonly ChangeRequest _hub;
public CompanyController(CPLopsEntities context, ChangeRequest hub)
{
    _context = context;
    _hub = hub;
}

public IActionResult Insert(Entry entry)
{
    Guid newId = CompanyDB.Instance.InsertEntry(entry);
    _hub.Send(newId);
    return Ok();
}

:客户端是一个WPF应用程序,我没有找到很多关于实现的信息。到目前为止,我发现的是:

private const string host = "https://xxxxxxxx.service.signalr.net";
private HubConnection connection;
private Thread thread;
public MainViewModel()
{
    thread = new Thread(() =>
    {
        connection = new HubConnectionBuilder()
        .WithUrl(host + "/com")
        .WithAutomaticReconnect()
        .Build();
        
        connection.On<Guid>("ReceiveMessage", g => ExternalLoadCompany(g));
        connection.StartAsync();
    });
    thread.Start();
}

private void ExternalLoadCompany(Guid id)
{
    if (ApiCall.GetCompany(id).Result is Company c)
    {
        Companies.Clear();
        Companies.Add(c);
    }
}

到目前为止,我的 WPF 应用程序无法识别 Web 服务发送的任何消息,这是有道理的,因为我没有对其进行身份验证,但是,我没有找到有关如何传递完整连接字符串的信息包括尝试注册我的 WPF 应用程序时的 AccessKey,到目前为止我发现的所有信息都是 blazor 应用程序或其他类型的 Web 应用程序。

I'm running a web-Service on Azure which connects to SignalR as following showen:

My Hub-Class:

public class ChangeRequest : Hub
{
    protected IHubContext<ChangeRequest> _context;

    public ChangeRequest(IHubContext<ChangeRequest> context) => _context = context;
    public Task? Send(Guid id) =>
        _context.Clients?.All?.SendAsync("SendMessage", id);
}

My Programm.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<CPLopsEntities>(options => options.UseSqlServer(@"Server=tcp:noris.database.windows.net,1433;Initial Catalog=CPLopsTest;Persist Security Info=False;User ID=user;Password=!Pw12345;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"));
builder.Services.AddTransient<ChangeRequest>();

builder.Services.AddSignalR().AddAzureSignalR("Endpoint=https://xxxxxxx.service.signalr.net;AccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;Version=1.0;");

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.UseAzureSignalR(r => r.MapHub<ChangeRequest>("/com"));

using (var scope = app.Services.CreateScope())
    scope.ServiceProvider.GetRequiredService<CPLopsEntities>().Database.Migrate();

app.Run();

When a new Entry is added by calling the web-Service, I call _hub.Send():

private readonly CPLopsEntities _context;
private readonly ChangeRequest _hub;
public CompanyController(CPLopsEntities context, ChangeRequest hub)
{
    _context = context;
    _hub = hub;
}

public IActionResult Insert(Entry entry)
{
    Guid newId = CompanyDB.Instance.InsertEntry(entry);
    _hub.Send(newId);
    return Ok();
}

Since my Client-Side is a WPF-Application, I did not found quiet a lot information about implementation. What I found so far is this:

private const string host = "https://xxxxxxxx.service.signalr.net";
private HubConnection connection;
private Thread thread;
public MainViewModel()
{
    thread = new Thread(() =>
    {
        connection = new HubConnectionBuilder()
        .WithUrl(host + "/com")
        .WithAutomaticReconnect()
        .Build();
        
        connection.On<Guid>("ReceiveMessage", g => ExternalLoadCompany(g));
        connection.StartAsync();
    });
    thread.Start();
}

private void ExternalLoadCompany(Guid id)
{
    if (ApiCall.GetCompany(id).Result is Company c)
    {
        Companies.Clear();
        Companies.Add(c);
    }
}

So far, my WPF-Application does not recognize any messages sent by the web-Service which makes sense, since I did not authenticate it, however, I found no information about how to pass the full Connectionstring including the AccessKey when trying to register my WPF-App and all information I found so far are blazor-apps or other kind of web-apps.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽清梦 2025-01-27 04:22:39

您的服务器端代码正在调用“SendMessage”,而客户端正在查找“ReceiveMessage”。服务器端正在调用客户端上的方法,但该方法不存在。

PS:您不需要启动该线程。 Task.Run 会更好。

Your server side code is calling "SendMessage" and the client is looking "ReceiveMessage". The server side is invoking a method on the client and it doesn't exist.

PS: You don't need to start that thread. Task.Run would be better.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文