簡體   English   中英

從任何Xamarin(Visual Studio 2017)android活動向MessageR集線器發送消息

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM