从客户端调用 SignalR Hub 方法锁定 Xamarin android App
Calling SignalR Hub method from client locks Xamarin android App
我终于得到了一个 SignalR Hub,可以使用 Microsoft.AspNet.SignalR 代替 Microsoft.AspNetCore.SignalR,我无法得到 Microsoft.AspNetCore.SignalR,不知道为什么。但我确实让另一个工作了。我能够使用 OnConnect 将 link 个客户端连接到连接 ID,并使用 OnDisconnect 将其删除。我的集线器代码是:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
using SignalrHub;
namespace SignalRChat
{
public class ChatHub : Hub
{
private static readonly List<User> Users = new List<User>();
public override Task OnConnected()
{
// string userName = Context.User.Identity.Name;
string userName = Context.QueryString["username"];
string org= Context.QueryString["organization"];
string dept = Context.QueryString["dept"];
string team = Context.QueryString["team"];
string firstname = Context.QueryString["firstname"];
string lastname = Context.QueryString["lastname"];
string connectionId = this.Context.ConnectionId;
// for now I just capture username and connection Id
var user = new User();
user.Name = userName;
user.ConnectionIds = connectionId;
try
{
Users.Add(user);
}
catch (Exception ex)
{
var msg = ex.Message;
}
// TODO: Broadcast the connected user
// send list of connected users to client
Send("Welcome " + userName, "Connected users are:");
foreach (var display in Users)
{
Send("",display.Name.ToString());
}
return base.OnConnected();
}
public override Task OnDisconnected(bool stopped)
{
string userName = Context.User.Identity.Name;
string connectionId = Context.ConnectionId;
var item = Users.Find(x => x.ConnectionIds == connectionId);
Users.Remove(item);
return base.OnDisconnected(true);
}
public void Send(string name, string message)
{
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(name, message);
}
public List<String> GetConnectedUsers()
{
List<string> UserNames = new List<string>();
foreach (var ConnectedUser in Users)
{
UserNames.Add(ConnectedUser.Name);
}
return UserNames;
}
}
}
一切正常,除了当我调用 GetConnectedUsers()
时,当我使用此代码 ConnecteduserList = client.ConnectedUsers();
从客户端调用它时,应用程序锁定,例如;集线器永远不会 returns 来自该方法。显然我错过了一些东西。谁能告诉我是什么?
应用程序中的客户端代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;
namespace ChatClient.Shared
{
class Client
{
//public string username;
private readonly string _platform;
private readonly HubConnection _connection;
private readonly IHubProxy _proxy;
public event EventHandler<string> OnMessageReceived;
public Client(string platform, string username)
{
string _username = "username=" + username;
_platform = platform;
_connection = new HubConnection("https://MyApp.com/SignalRhub", _username);
_proxy = _connection.CreateHubProxy("chathub");
}
public async Task Connect()
{
await _connection.Start(); _proxy.On("broadcastMessage", (string platform, string message) =>
{
if (OnMessageReceived != null)
OnMessageReceived(this, string.Format("{0}: {1}", platform, message));
});
Send("Connected");
}
public List<string> ConnectedUsers()
{
List<string> Users = new List<string>();
// Locks up when this line is esecuted. The server log has nothing in it.
Users = _proxy.Invoke<List<string>>("GetConnectedUsers").Result;
return Users;
}
public Task Send(string message)
{
return _proxy.Invoke("Send", _platform, message);
}
}
}
感谢 GitHub 的 David Fowler 为本文档 (https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#avoid-using-taskresult-and-taskwait) 提供了 link,我能够通过如下更改代码来实现它:
在客户端:
来自:
public List<string> ConnectedUsers()
{
// Hangs on this line
List<string> Users = _proxy.Invoke<List<string>>("getConnectedUsers").Result;
return Users;
}
收件人:
public async Task <List<string>> ConnectedUsers()
{
List<string> Users = await _proxy.Invoke<List<string>>("getConnectedUsers");
return Users;
}
Client.cs 中对 ConnectedUsers 函数的调用也已更改:
来自:
List<string> userList = client.ConnectedUsers();
收件人:
List<string> userList = await client.ConnectedUsers();
无需更改集线器代码。
我终于得到了一个 SignalR Hub,可以使用 Microsoft.AspNet.SignalR 代替 Microsoft.AspNetCore.SignalR,我无法得到 Microsoft.AspNetCore.SignalR,不知道为什么。但我确实让另一个工作了。我能够使用 OnConnect 将 link 个客户端连接到连接 ID,并使用 OnDisconnect 将其删除。我的集线器代码是:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
using SignalrHub;
namespace SignalRChat
{
public class ChatHub : Hub
{
private static readonly List<User> Users = new List<User>();
public override Task OnConnected()
{
// string userName = Context.User.Identity.Name;
string userName = Context.QueryString["username"];
string org= Context.QueryString["organization"];
string dept = Context.QueryString["dept"];
string team = Context.QueryString["team"];
string firstname = Context.QueryString["firstname"];
string lastname = Context.QueryString["lastname"];
string connectionId = this.Context.ConnectionId;
// for now I just capture username and connection Id
var user = new User();
user.Name = userName;
user.ConnectionIds = connectionId;
try
{
Users.Add(user);
}
catch (Exception ex)
{
var msg = ex.Message;
}
// TODO: Broadcast the connected user
// send list of connected users to client
Send("Welcome " + userName, "Connected users are:");
foreach (var display in Users)
{
Send("",display.Name.ToString());
}
return base.OnConnected();
}
public override Task OnDisconnected(bool stopped)
{
string userName = Context.User.Identity.Name;
string connectionId = Context.ConnectionId;
var item = Users.Find(x => x.ConnectionIds == connectionId);
Users.Remove(item);
return base.OnDisconnected(true);
}
public void Send(string name, string message)
{
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(name, message);
}
public List<String> GetConnectedUsers()
{
List<string> UserNames = new List<string>();
foreach (var ConnectedUser in Users)
{
UserNames.Add(ConnectedUser.Name);
}
return UserNames;
}
}
}
一切正常,除了当我调用 GetConnectedUsers()
时,当我使用此代码 ConnecteduserList = client.ConnectedUsers();
从客户端调用它时,应用程序锁定,例如;集线器永远不会 returns 来自该方法。显然我错过了一些东西。谁能告诉我是什么?
应用程序中的客户端代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;
namespace ChatClient.Shared
{
class Client
{
//public string username;
private readonly string _platform;
private readonly HubConnection _connection;
private readonly IHubProxy _proxy;
public event EventHandler<string> OnMessageReceived;
public Client(string platform, string username)
{
string _username = "username=" + username;
_platform = platform;
_connection = new HubConnection("https://MyApp.com/SignalRhub", _username);
_proxy = _connection.CreateHubProxy("chathub");
}
public async Task Connect()
{
await _connection.Start(); _proxy.On("broadcastMessage", (string platform, string message) =>
{
if (OnMessageReceived != null)
OnMessageReceived(this, string.Format("{0}: {1}", platform, message));
});
Send("Connected");
}
public List<string> ConnectedUsers()
{
List<string> Users = new List<string>();
// Locks up when this line is esecuted. The server log has nothing in it.
Users = _proxy.Invoke<List<string>>("GetConnectedUsers").Result;
return Users;
}
public Task Send(string message)
{
return _proxy.Invoke("Send", _platform, message);
}
}
}
感谢 GitHub 的 David Fowler 为本文档 (https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#avoid-using-taskresult-and-taskwait) 提供了 link,我能够通过如下更改代码来实现它:
在客户端: 来自:
public List<string> ConnectedUsers()
{
// Hangs on this line
List<string> Users = _proxy.Invoke<List<string>>("getConnectedUsers").Result;
return Users;
}
收件人:
public async Task <List<string>> ConnectedUsers()
{
List<string> Users = await _proxy.Invoke<List<string>>("getConnectedUsers");
return Users;
}
Client.cs 中对 ConnectedUsers 函数的调用也已更改: 来自:
List<string> userList = client.ConnectedUsers();
收件人:
List<string> userList = await client.ConnectedUsers();
无需更改集线器代码。