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

从服务器获取客户端数据的信号器解决方案

  •  1
  • Hayha  · 技术社区  · 7 年前

    我知道当调用来自服务器时,signer不能从客户端返回。在Signal的github存储库上,我要求提供一种解决方法( https://github.com/aspnet/SignalR/issues/1329 )他们建议我通过将结果从客户端发送到服务器,再发送到中心中的另一个方法来获得结果,因此使用TaskCompletionSource和一些连接元数据来捕获结果,但我一直在研究如何做到这一点

    控制器服务器:

    [HttpPut("send/{message}")]
    public async Task<IActionResult> SendMessage(string message)
    {
        if (!ModelState.IsValid) return BadRequest(ModelState.Values);
    
        string connectionId = Request.Headers["connectionId"];
        await _chatHubContext.Clients.Client(connectionId).InvokeAsync("send");
    
        // Catch the call of MessageReceived and get the chat status
    
        return new OkObjectResult(new EmptyJsonResult() { Result = "OK" }); 
    
    }
    

    集线器服务器

    public class ChatHub : Hub
    {
        public Task MessageReceive(bool chatStatus)
        {
            // Tell controller that message is received
        }
    }
    

    Angular 4客户端

    import { Component, Inject } from '@angular/core';
    import { HubConnection } from '@aspnet/signalr-client';
    
    @Component({
      selector: 'chat',
      templateUrl: './chat.component.html',
      styleUrls: ['./chat.component.css']
    })
    /** chat component*/
    export class ChatComponent {
      hubConnection: HubConnection;
      chatStatus = false;
    
      /** chat ctor */
      constructor( @Inject('BASE_URL') private originUrl: string) {
        this.hubConnection = new HubConnection(`${this.originUrl}chat`);
    
        setInterval(() => {
          this.chatStatus = !this.chatStatus;
        },
          5000);
    
        this.hubConnection
          .start()
          .then(() => {
            this.hubConnection.on('send', (message: string) => {
              if (this.chatStatus) {
                //send message
              }
              this.hubConnection
                .invoke('messageReceived', this.chatStatus);
            });
          });
    
      }
    }
    

    正如您在这段代码中所看到的,我不知道在控制器方法和集线器方法中要做什么,才能知道方法MessageReceive被调用了,并获得返回以将其发送回控制器请求。

    1 回复  |  直到 7 年前
        1
  •  3
  •   aaron    6 年前

    “通过对连接元数据和 TaskCompletionSource 您还可以使其看起来很像返回值的方法调用。"

    控制器服务器 :

    注射 HttpConnectionManager .

    // using Microsoft.AspNetCore.Http.Connections.Internal;
    
    public async Task<IActionResult> SendMessage(string message)
    {
        string connectionId = Request.Headers["connectionId"];
    
        var chatStatus = await Send(connectionId, message);
    
        return new OkObjectResult(new { Result = "OK", ChatStatus = chatStatus });
    }
    
    private async Task<bool> Send(string connectionId, string message)
    {
        var tcs = new TaskCompletionSource<bool>();
    
        _connectionManager.TryGetConnection(connectionId, out HttpConnectionContext connection);
    
        connection.Items.Add("tcs", tcs);
    
        await _chatHubContext.Clients.Client(connectionId).SendAsync("send", message);
    
        var chatStatus = await tcs.Task;
    
        connection.Items.Remove("tcs");
    
        return chatStatus;
    }
    

    集线器服务器 :

    public Task MessageReceived(bool chatStatus)
    {
        Context.Items.TryGetValue("tcs", out object obj);
    
        var tcs = (TaskCompletionSource<bool>)obj;
    
        tcs.SetResult(chatStatus);
    
        return Task.CompletedTask;
    }
    

    Angular 4客户端 :

    // No change
    
    推荐文章