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
最满意答案
在这种情况下,哈希检查应该快得多,然后是嵌套循环,即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 propertiesNow 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
. ThisHashSet
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 toif (set.Add(thisProject.Tasks[i]))
and processing within thisif
相关问答
更多-
.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 ... -
使用bool来确定一个进程是否是c#中的无限循环(using a bool to determine if a process is an infinite loop in c#)[2021-07-11]
如果这两个数字从不相互接近,那将是无限的。 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() ...
-
替换for循环用于提高性能(with weighted.mean)(Replacing for-loops with apply to improve perfomance (with weighted.mean))[2022-02-05]
在@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 ... -
将数组索引增加1 C#(Increase an array index by 1 C#)[2023-11-04]
听起来你真正想要的是以下内容。 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); ...