从任何Xamarin(Visual Studio 2017)android活动发送消息到SignalR hub

问题描述 投票:1回答:1

我已经能够从一个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方法从集线器接收消息。这一切都完美无瑕。

我的客户端代码:此代码是从堆栈溢出工作示例中复制的,我将其修改为我的要求。

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);

奇迹般有效。

c# android xamarin.android signalr signalr.client
1个回答
0
投票

或者你可以尝试单例模式,例如(只是为了提供想法,你需要根据自己的需要编写代码):

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();

© www.soinside.com 2019 - 2024. All rights reserved.