[英]Send message to SignalR hub from any Xamarin (Visual Studio 2017) android activity
我已經能夠從HTML頁面,aspx頁面和Xamarin客戶端創建並接收來自SignalR集線器的消息,這是我真正需要的應用程序,以便在Visual Studio中使用Xamarin來使用Microsoft.AspNet.SignalR.Client v2.4.1 2017年。一旦我的Xamarin應用驗證了用戶身份后,我便開始與集線器的連接,接下來我組織一個活動來接收消息。 所有這些工作都很好,而且由於連接了事件,無論當前活動是什么活動,我都可以在android應用程序中接收消息。 現在,我已經完成了這項工作,我希望能夠從客戶端向集線器發送消息,而無需創建與集線器的其他連接。 我看過靜態類,但無法正常工作。 我的代碼是:
這是驗證用戶身份后執行的代碼:
// Start SignalR connection
Client client = new Client(MyUser.Firstname + " " + MyUser.Lastname, MyUser.Username);
await client.Connect();
// Wire up the message received event
client.OnMessageReceived += (sender2, message) => RunOnUiThread(() => showMessage(message));
用戶可以在此處從一個視圖瀏覽到showMessage
視圖,並能夠通過事件和showMessage
方法從中心接收消息。 所有這些都完美無缺。
我的客戶代碼:此代碼是從堆棧溢出工作示例復制而來的,我將其修改為我的要求。
namespace ChatClient.Shared
{
class Client
{
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://Example.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 async Task<List<string>> ConnectedUsers()
{
List<string> Users = await _proxy.Invoke<List<string>>("getConnectedUsers");
return Users;
}
public Task Send(string message)
{
return _proxy.Invoke("Send", _platform, message);
}
}
}
現在,我需要使用登錄后立即創建的連接向集線器發送消息,以將其分發給所有連接的用戶。 我無法弄清楚該怎么做,我嘗試使用靜態類並嘗試使用在網絡上找到的方法,但似乎沒有任何效果。
我的中心代碼:
public class ChatHub : Hub
{
private static readonly List<User> Users = new List<User>();
public override Task OnConnected()
{
string userName = Context.QueryString["username"];
string firstname = Context.QueryString["firstname"];
string lastname = Context.QueryString["lastname"];
string connectionId = this.Context.ConnectionId;
var user = new User();
user.Name = userName;
user.ConnectionIds = connectionId;
try
{
Users.Add(user);
}
catch (Exception ex)
{
var msg = ex.Message;
}
// send list of connected users to client as a test
Send("Welcome " + userName, "Connected users are:");
foreach (var display in Users)
{
Send("",display.Name.ToString());
}
// test sending to a specific user
SendOne(connectionId, userName, "This is to a specific user.");
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);
Send(item.Name , " disconnected.");
Users.Remove(item);
return base.OnDisconnected(true);
}
public void SendOne(string connectionId, string userName, string message)
{
Clients.Client(connectionId).broadcastMessage(userName, message);
}
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;
}
}
我將在集線器中做很多其他事情,但是現在我需要讓客戶端發送消息而不創建另一個連接
在其他視圖/活動中對用戶進行身份驗證之后,是否可以訪問我創建的連接?
*更新*
我根據下面的Leo Zhu的答案更改了代碼,但是當我嘗試實例化該類時,我得到了一個錯誤:
Client client = new Client.GetInstance(MyUser.Firstname + " " + MyUser.Lastname, MyUser.Username);
GetInstance does not exist
。 不知道為什么它沒有被“發現”。
*更新*
從該行中刪除了new
關鍵字:
Client client = new Client.GetInstance(MyUser.Firstname + " " + MyUser.Lastname, MyUser.Username);
現在顯示為:
Client client = Client.GetInstance(MyUser.Firstname + " " + MyUser.Lastname, MyUser.Username);
奇跡般有效。
或者,您也可以嘗試使用單例模式(例如,提供想法,您需要根據自己的需要進行編碼):
public sealed class Client
{
// A private constructor to restrict the object creation from outside
private Client()
{
...
}
// A private static instance of the same class
private static Client instance = null;
public static Client GetInstance()
{
// create the instance only if the instance is null
if (instance == null)
{
instance = new Client();
}
// Otherwise return the already existing instance
return instance;
}
}
那么您可以通過Client.GetInstance();
調用Client.GetInstance();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.