今日、SignalRを試してみましたが、本当にすてきです。基本的に私が達成したかったのは次のとおりです。
デバイスが接続するとすぐに、最初のデバイスにメッセージを送信する必要があります。接続されているデバイスが複数ある場合は、2つのメッセージを送信したいと思います。 1対すべて除く最後に接続されたクライアント。そして、最後に接続されたクライアントへの1つのメッセージのみ。
私が使用しているコードは、カスタムAPIコントローラーに配置して基本的にアクションを呼び出すと完璧に機能しますが、それは私が望んでいることではありません。
ユーザーの操作なしでデバイスがOnConnected
内に接続したらすぐにメッセージを送信したいのですが、コードをOnConnected
オーバーライド内に配置すると、機能しなくなります。特定のクライアント(最初に接続されたものと最後に接続されたもの)には送信されなくなります。
私は数時間頭を叩いているので、誰かがこれを手伝ってくれることを願っています。
public override System.Threading.Tasks.Task OnConnected()
{
UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1);
int amountOfConnections = UserHandler.ConnectedIds.Count;
var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault();
var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList();
if (amountOfConnections == 1)
{
Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one");
}
else
{
Clients.Clients(allExceptLast).hello("Send to everyone except last");
Clients.Client(lastConnection.Key).hello("Send to only the last one");
}
return base.OnConnected();
}
すべての助けをありがとう(みんなに賛成)。実際に問題を見つけました..それは私のクライアントの内部にありました。最初に「hello」関数をサブスクライブし、その後、HubConnectionを開始しました。この順序を変更するとすぐに、すべてが正常に機能しました。
次のクライアントコードで動作しました。
private async Task ConnectToSignalR()
{
var hubConnection = new HubConnection("url");
hubConnection.Headers["x-zumo-application"] = "clientapikey";
IHubProxy proxy = hubConnection.CreateHubProxy("ChatHub");
proxy.On<string>("hello", async (msg) =>
{
Console.WriteLine(msg);
});
await hubConnection.Start();
}
私があなたの質問から何かを見逃さない限り、解決策は私にはかなり単純に見えます、あなたはただ使用に切り替える必要があります
Clients.Caller.hello("Send to only the last one");
最後に接続されたIDが誰であるかを理解しようとする代わりに。他のものと同じように、あなたは使うことができます:
Clients.Others.hello("Send to everyone except last");
セットアップするすべてのロジックは必要ありません。これらの2行は必要なことを実行し、OnConnected
内で機能します。
まだ接続を確立していないため、現時点では、OnConnected
内でクライアントの.hello()
関数を呼び出そうとすることはできません。ただし、サーバーハブメソッドを定義し、接続_.done
_コールバックですぐに呼び出すことができます。次に、新しいサーバーメソッドで、現在OnConnected
にあるロジックを再割り当てできます。
これにより、セットアップが大幅に変更され、いくつかの追加手順が導入されますが、次の例を確認してください...
_// WhateverHub
public override Task OnConnected()
{
return base.OnConnected()
}
public void AfterConnected()
{
// if(stuff) -- whatever if/else first user/last user logic
// {
Clients.Caller.hello("message")
// }
}
_
_var proxy= $.connection.whateverHub;
proxy.client.hello = function(message) {
// last step in event chain
}
$.connection.hub.start().done(function () {
proxy.server.afterConnected() // call AfterConnected() on hub
});
_
したがって、ここでの基本的な考え方は、最初に
.done(function() { ... });
server.afterConnected()
を呼び出します.hello()
クライアント関数を呼び出します注-この実装はJavaScriptクライアント用です-しかし、同じアイデアを.netクライアントに変換できます。これは主にアーキテクチャ上の問題です。
ええと...あなたはタスクを返しています...だから私はそれが問題かもしれないと思います...あなたは最初にあなたのコードを実行してからタスクを返すべきです...またはContinueWithを置くべきです...のように...
public override Task OnConnected()
{
Task task = new Task(() =>
{
UserHandler.ConnectedIds.Add(Context.ConnectionId, UserHandler.ConnectedIds.Count + 1);
int amountOfConnections = UserHandler.ConnectedIds.Count;
var lastConnection = UserHandler.ConnectedIds.OrderBy(x => x.Value).LastOrDefault();
var allExceptLast = UserHandler.ConnectedIds.Take(amountOfConnections - 1).Select(x => x.Key).ToList();
if (amountOfConnections == 1)
{
Clients.Client(UserHandler.ConnectedIds.First().Key).hello("Send to only(also first) one");
}
else
{
Clients.Clients(allExceptLast).hello("Send to everyone except last");
Clients.Client(lastConnection.Key).hello("Send to only the last one");
}
});
task.ContinueWith(base.OnConnected());
return task;
}
私はそれをテストしていません...それはただの推測です...