首页 \ 问答 \ SignalR解决方法从服务器获取客户端数据(SignalR workaround to get client data from server)

SignalR解决方法从服务器获取客户端数据(SignalR workaround to get client data from server)

我知道当服务器发出invokation时,SignalR无法从客户端返回。 在SignalR的github存储库中,我要求一个解决方法( https://github.com/aspnet/SignalR/issues/1329 ),他们建议我通过将它从客户端发送到服务器到集线器中的另一个方法来获得结果所以使用TaskCompletionSource和一些连接元数据来捕获结果,但我仍然坚持如何做到这一点

Controller Server:

[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" }); 

}

Hub服务器

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);
        });
      });

  }
}

正如您在此代码中看到的那样,我不知道在控制器方法和Hub方法中要做什么来知道调用MessageReceive方法并让他返回将其发送回控制器请求。


I know that SignalR can't have a return from client when invokation came from the server. On the github repository of SignalR I asked for a workaround (https://github.com/aspnet/SignalR/issues/1329) and they suggest me to get the result by sending it from the client to server to another method in the hub and so use TaskCompletionSource and some connection metadata to catch the result, but I'm stuck on how to do this

Controller Server :

[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" }); 

}

Hub Server

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

Angular 4 client

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);
        });
      });

  }
}

As you can see on this code, I don't know what to do in the controller method and the Hub method to know that the method MessageReceive was called and to get his return to send it back to the controller request.


原文:https://stackoverflow.com/questions/48464800
更新时间:2023-11-29 17:11

最满意答案

在这种情况下,哈希检查应该快得多,然后是嵌套循环,即O(n)vs O(n ^ 2)

首先,提供您自己的相等比较器

class TaskComparer : IEqualityComparer<Task> {
    public bool Equals(Task x, Task y) {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        if (x.GetType() != y.GetType()) return false;
        return string.Equals(x.Name, y.Name) && string.Equals(x.ResourceNames, y.ResourceNames);
    }

    public int GetHashCode(Task task) {
        unchecked {
            return 
                ((task?.Name?.GetHashCode()         ?? 0) * 397) ^ 
                 (task?.ResourceNames?.GetHashCode() ?? 0);
        }
    }
}

不要过分担心GetHashCode函数的实现; 这只是一个肉鸡板代码,它从其属性中组成一个唯一的哈希码

现在你有了这个类用于比较和散列,你可以使用下面的代码来删除你的欺骗

var set = new HashSet<Task>(new TaskComparer());
for (int i = thisProject.Tasks.Count - 1; i >= 0; --i) {
    if (!set.Add(thisProject.Tasks[i]))
        thisProject.Tasks[i].Delete();
}

正如您所注意到的那样,您只需扫描所有元素,同时将它们存储到HashSet 。 这个HashSet将根据我们的相等比较器检查提供的元素是否重复。

现在,由于您要删除它,删除检测到的欺骗。 您可以通过将条件反转为if (set.Add(thisProject.Tasks[i]))并在此内处理来修改此代码以简单地提取Unique项而不是删除if (set.Add(thisProject.Tasks[i]))


A hash check should be lot faster in this case then nested-looping i.e. O(n) vs O(n^2)

First, provide a equality comparer of your own

class TaskComparer : IEqualityComparer<Task> {
    public bool Equals(Task x, Task y) {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        if (x.GetType() != y.GetType()) return false;
        return string.Equals(x.Name, y.Name) && string.Equals(x.ResourceNames, y.ResourceNames);
    }

    public int GetHashCode(Task task) {
        unchecked {
            return 
                ((task?.Name?.GetHashCode()         ?? 0) * 397) ^ 
                 (task?.ResourceNames?.GetHashCode() ?? 0);
        }
    }
}

Don't worry too much about the GetHashCode function implementation; this is just a broiler-plate code which composes a unique hash-code from its properties

Now you have this class for comparison and hashing, you can use the below code to remove your dupes

var set = new HashSet<Task>(new TaskComparer());
for (int i = thisProject.Tasks.Count - 1; i >= 0; --i) {
    if (!set.Add(thisProject.Tasks[i]))
        thisProject.Tasks[i].Delete();
}

As you notice, you are simply scanning all your elements, while storing them into a HashSet. This HashSet will check, based on our equality comparer, if the provided element is a duplicate or not.

Now, since you want to delete it, the detected dupes are deleted. You can modify this code to simply extract the Unique items instead of deleting the dupes, by reversing the condition to if (set.Add(thisProject.Tasks[i])) and processing within this if

相关问答

更多
  • .Net会自动完成。 看起来你已经达到了内存的限制,一个.Net进程可以使用它的对象(在32位机器上,这是2个标准,或者通过使用/ 3GB启动开关来达到3GB,对于Leppie&Eric Lippert的信息感谢)。 重新思考你的算法,或者对64位机器的改变可能会有所帮助。 .Net does that automatically. Looks like you have reached the limit of the memory one .Net process can use for its obj ...
  • 单击该按钮时,您可以更改标签的值,增加其当前值。 此解决方案使用%运算符(C#参考) private void bttnAdd_Click(object sender, EventArgs e) { int currentValue; // Tries to parse the text to an integer and puts the result in the currentValue variable if (int.TryParse(lblBet.Text, out cu ...
  • 在这种情况下,哈希检查应该快得多,然后是嵌套循环,即O(n)vs O(n ^ 2) 首先,提供您自己的相等比较器 class TaskComparer : IEqualityComparer { public bool Equals(Task x, Task y) { if (ReferenceEquals(x, y)) return true; if (ReferenceEquals(x, null)) return false; if ...
  • 如果这两个数字从不相互接近,那将是无限的。 a总是增加1, b总是减少1 第一种情况: a == b 第二种情况: 如果它们都是正数,那么它们将相等,如果b至少比a多2,并且a和b a和可以被2整除:那么第二个条件是: (ba)> = 2 &&((b + a)%2 == 0) 第三种情况: 两者都是消极的,所以a会变大, b会变小。 第二种情况也适用同样的规则,但我们取绝对值,这样我们可以制作第二种情况,它可以适用于第二种情况和第三种情况: (abs(b)-abs(a))> = 2 &&((abs(b)+ ...
  • 您正在尝试访问错误的索引array[length]=num; ,如果数组的大小是length ,则无法访问length -th元素。 您必须在重新分配后移动写入: /*Check for valid inputs and put into array*/ while((scanf("%d", &num)) != EOF){ length++; array = realloc(array, length*sizeof(int)); if(array == NULL) pb_memory() ...
  • 在@joran的答案基础上建立正确的结果: with(A, rev(cumsum(rev(X1*X2)) / cumsum(rev(X2)))) # [1] 1.800000 2.333333 3.000000 还要注意,这比sapply / lapply方法lapply 。 Building upon @joran's answer to produce the correct result: with(A, rev(cumsum(rev(X1*X2)) / cumsum(rev(X2)))) # [1 ...
  • 听起来你真正想要的是以下内容。 Random rand = new Random(); int numberOfRolls = Convert.ToInt32(textBox1.Text); int[] counters = new int[16]; //16 different possible sums (3 to 18) for (int i = 0; i < numberOfRolls; i++) { int sum = rand.Next(1, 7) + rand.Next(1, 7) ...
  • ++增量运算符仅将值增加1 for (int i = 0; i < 10; i++) 要增加两次: for (int i = 0; i < 10; i+=2) { Console.Write("Enter Score{0}: ", i); } 阅读更多: Increment(++)和Decrement( - )运算符 | If | Equivalent Action | Return value | | v ...
  • PowerShell 3.0引入了Where-Object (别名: Where ,?),可以在没有脚本块的情况下直接检查属性。 当执行脚本块时,PowerShell与其他语言一样,会创建一个新的执行上下文,并且在解释型语言中它非常昂贵。 将旧符号与脚本块一起使用的唯一原因是: 拥有PS1 / PS2兼容代码; 执行复杂的检查; 除了检查本身以外还有其他的工作。 至于你的代码,两个片段都使用其他地方的脚本块,流水线(它比foreach语句慢5-10倍),并且不必要地测量Get-ADGroup时间,所以我们可 ...
  • 我认为是递归的经典案例。 function createHTML(data) { var item = data.shift(), div, child; if (item) { div = document.createElement("DIV"); div.id = item.id; child = createHTML(data, div); if (child) div.appendChild(child); ...

相关文章

更多

最新问答

更多
  • h2元素推动其他h2和div。(h2 element pushing other h2 and div down. two divs, two headers, and they're wrapped within a parent div)
  • 创建一个功能(Create a function)
  • 我投了份简历,是电脑编程方面的学徒,面试时说要培训三个月,前面
  • PDO语句不显示获取的结果(PDOstatement not displaying fetched results)
  • Qt冻结循环的原因?(Qt freezing cause of the loop?)
  • TableView重复youtube-api结果(TableView Repeating youtube-api result)
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • SQL Server 2014版本支持的最大数据库数(Maximum number of databases supported by SQL Server 2014 editions)
  • 我如何获得DynamicJasper 3.1.2(或更高版本)的Maven仓库?(How do I get the maven repository for DynamicJasper 3.1.2 (or higher)?)
  • 以编程方式创建UITableView(Creating a UITableView Programmatically)
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何防止调用冗余函数的postgres视图(how to prevent postgres views calling redundant functions)
  • Sql Server在欧洲获取当前日期时间(Sql Server get current date time in Europe)
  • 设置kotlin扩展名(Setting a kotlin extension)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 如何在vim中启用python3?(How to enable python3 in vim?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • dedecms如何安装?
  • 在哪儿学计算机最好?
  • 学php哪个的书 最好,本人菜鸟
  • 触摸时不要突出显示表格视图行(Do not highlight table view row when touched)
  • 如何覆盖错误堆栈getter(How to override Error stack getter)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • USSD INTERFACE - > java web应用程序通信(USSD INTERFACE -> java web app communication)
  • 电脑高中毕业学习去哪里培训
  • 正则表达式验证SMTP响应(Regex to validate SMTP Responses)