代码之家  ›  专栏  ›  技术社区  ›  Deadpool

使用信号核心将信息从控制器方法发送到角度

  •  6
  • Deadpool  · 技术社区  · 8 年前

    我正在尝试使用signaler for asp net core 2.1,以便从控制器方法发送消息,该方法调用是从角度上的测试按钮触发的。
    我期望的行为是,当我单击按钮时,我的服务调用controller方法,该方法发送测试消息。然后,我将简单地记录消息。

    我想在一个服务中对此进行管理,以避免所有组件中的代码重复。

    我读过一些例子,比如 this question about using SignalR in a service (我用了第二种方法)和 this article the official docs 但即使应用这些概念,似乎也行不通。
    (所以,或者我完全用错了方法,或者仍然缺少一些东西,但我无法找出是什么…)

    客户端成功连接到消息中心 如果我按一下按钮, 方法被击中了 但是 我没收到任何消息 相反,我在chrome控制台中得到了这个警告:

    警告:找不到名为“sendaync”的客户端方法。

    发送消息很好,问题在于接收它们…

    问题是: 我做错什么了?误差是在后端还是在角端?


    我和你分享我所有的密码 :

    >启动.cs

    public void ConfigureServices(IServiceCollection services)
    {
       //...
       services.AddSignalR();
    }
    //...
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
       //...
       app.UseSignalR(routes =>
       {
          //...
          routes.MapHub<MessageHub>("/messagehub");
          //...
       });
    }
    

    >消息中心.cs

    public class MessageHub : Hub<ITypedHubClient>
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
    
    public interface ITypedHubClient
    {
        Task SendAsync(string title, string name, string message);
    }
    

    >消息控制器.cs

    IHubContext<MessageHub, ITypedHubClient> _messageHubContext;
    
    public MessageController(IHubContext<MessageHub, ITypedHubClient> messageHubContext)
    {
        _messageHubContext = messageHubContext;
    }
    
    [HttpPost("Test")]
    public async Task<IActionResult> Test()
    {
        try
        {
            await _messageHubContext.Clients.All.SendAsync("ReceiveMessage","test", "test");
    
            return Ok(true);
        }
        catch (Exception e)
        {
            return BadRequest(e);
        }
    }
    

    >通信服务

    @Injectable()
    export class CommunicationService {
    
      private _hubConnection: HubConnection | undefined;
      public async: any;
      message = '';
      messages: string[] = [];
    
      private newmessage = new Subject<string>();
      message$ = this.newmessage.asObservable();
    
    
      constructor() {
        this._hubConnection = new signalR.HubConnectionBuilder()
          .withUrl('/messagehub')
          //.configureLogging(signalR.LogLevel.Information)
          .configureLogging(signalR.LogLevel.Debug)
          .build();
    
        this._hubConnection.start().catch(err => console.error(err.toString()));
    
        this._hubConnection.on('SendMessage', (user: any, message:any) => {
          const received = `Received: ${message}`;
          //this.messages.push(received);
          this.newmessage.next(received);
          console.log("got something new...", received);
        });
      }
    
      clear() {
        this.newmessage.next("");
      }
    
      public sendMessage(): void {
        const data = `Sent: ${this.message}`;
    
        if (this._hubConnection) {
          this._hubConnection.invoke('SendMessage', 'AAA' ,data);
        }
        this.messages.push(data);
      }
    }
    
    1 回复  |  直到 8 年前
        1
  •  10
  •   J.Loscos    8 年前

    在Signaler Core 2.1中,可以使用强类型集线器在接口中声明可以对客户端调用哪些操作:

    public class MessageHub : Hub<ITypedHubClient>
    {
        public async Task SendMessage(string title, string user, string message)
        {
            await Clients.All.SendMessageToClient(title, user, message);
        }
    }
    public interface ITypedHubClient
    {
        Task SendMessageToClient(string title, string name, string message);
    }
    

    在控制器中:

        IHubContext<MessageHub, ITypedHubClient> _messageHubContext;
    
        public async Task<IActionResult> Test()
        {
            await _messageHubContext.Clients.All.SendMessageToClient("test", "test", "test");
            return Ok("ok");
        }
    

    在客户中:

    _hubConnection.on('SendMessageToClient', (title, user, message) => {
        const received = `title: ${title}, name: ${user}, message: ${message}`;
        console.log(received);
    });
    

    如果不使用强类型中心,则要在客户端调用相同的方法,它将变成:

    public class MessageHub : Hub
    {
        public async Task SendMessage(string title, string user, string message)
        {
            await Clients.All.SendAsync("SendMessageToClient", title, user, message);
        }
    }
    

    在这种情况下,可以在客户端代理上使用sendaync方法,它的第一个参数是要调用的方法的名称。

    更新: 当我们用接口定义强类型中心时,所有接口方法都必须返回一个任务。使用自定义方法,signaler生成调用sendcoreasync的方法。允许我们异步调用这些方法。

    如果接口方法的返回类型不是任务,则会出现错误:所有客户端代理方法都必须返回“system.threading.tasks.task”