简体   繁体   English

从任何Xamarin(Visual Studio 2017)android活动向MessageR集线器发送消息

[英]Send message to SignalR hub from any Xamarin (Visual Studio 2017) android activity

I've been able to create and receive messages from a SignalR hub from a html page, aspx page and an Xamarin client which is the app I really need it for using Microsoft.AspNet.SignalR.Client v2.4.1 using Xamarin in Visual Studio 2017. Once my Xamarin app authenticates the user I start the connection to the hub, next I wire up an event to receive messages. 我已经能够从HTML页面,aspx页面和Xamarin客户端创建并接收来自SignalR集线器的消息,这是我真正需要的应用程序,以便在Visual Studio中使用Xamarin来使用Microsoft.AspNet.SignalR.Client v2.4.1 2017年。一旦我的Xamarin应用验证了用户身份后,我便开始与集线器的连接,接下来我组织一个活动来接收消息。 All of this works just fine and I can receive messages in the android app no matter what activity is the current activity thanks to the event that is wired up. 所有这些工作都很好,而且由于连接了事件,无论当前活动是什么活动,我都可以在android应用程序中接收消息。 Now that I have this working I want to be able to send a message from the client to the hub without creating another connection to the hub. 现在,我已经完成了这项工作,我希望能够从客户端向集线器发送消息,而无需创建与集线器的其他连接。 I've looked at static classes, but cannot get that to work. 我看过静态类,但无法正常工作。 My code is: 我的代码是:

This is the code that is executed after the user is authenticated: 这是验证用户身份后执行的代码:

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

From here the user can navigate from view to view and is able to receive messages from the hub via the event and the showMessage method. 用户可以在此处从一个视图浏览到showMessage视图,并能够通过事件和showMessage方法从中心接收消息。 This all works flawlessly. 所有这些都完美无缺。

My Client Code: This code was copied from a stack overflow working example, I modified it to my requirements. 我的客户代码:此代码是从堆栈溢出工作示例复制而来的,我将其修改为我的要求。

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

Now what I need to do is send a message to the hub using the connection created just after the logon to be distributed to all connected users. 现在,我需要使用登录后立即创建的连接向集线器发送消息,以将其分发给所有连接的用户。 I cannot figure out how to do that, I've tried using a static class and attempted to use methods I've found on the web, but nothing seems to work. 我无法弄清楚该怎么做,我尝试使用静态类并尝试使用在网络上找到的方法,但似乎没有任何效果。

My Hub code: 我的中心代码:

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

There are a lot of other things I will be doing in the hub, but for now I need to get the client to send messages without creating another connection 我将在集线器中做很多其他事情,但是现在我需要让客户端发送消息而不创建另一个连接

Is there a way I can access the connection created after the user is authenticated in other views/activities? 在其他视图/活动中对用户进行身份验证之后,是否可以访问我创建的连接?

* Update * *更新*

I changed my code in accordance with Leo Zhu's answer below, however I get an error when I try to instantiate the class on the line: 我根据下面的Leo Zhu的答案更改了代码,但是当我尝试实例化该类时,我得到了一个错误:

Client client = new Client.GetInstance(MyUser.Firstname + " " + MyUser.Lastname, MyUser.Username);

GetInstance does not exist when it actually does. GetInstance does not exist No idea why it isn't "found". 不知道为什么它没有被“发现”。

* Update * *更新*

Removed the new keyword from the line: 从该行中删除了new关键字:

Client client = new Client.GetInstance(MyUser.Firstname + " " + MyUser.Lastname, MyUser.Username);

It now reads: 现在显示为:

Client client = Client.GetInstance(MyUser.Firstname + " " + MyUser.Lastname, MyUser.Username);

Works like a charm. 奇迹般有效。

Or you can try the singleton pattern,for example (Just to provide ideas,you need to code to your own needs): 或者,您也可以尝试使用单例模式(例如,提供想法,您需要根据自己的需要进行编码):

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

  }

then you could call by Client.GetInstance(); 那么您可以通过Client.GetInstance();调用Client.GetInstance();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Xamarin(Android)单元测试在Visual Studio 2017中 - Xamarin (Android) Unit Tests in Visual Studio 2017 从.net socket发送/接收消息到signalR hub - Send/Recieve message from .net socket to signalR hub 如何防止Visual Studio中断SignalR集线器中引发的异常? - How to prevent Visual Studio from breaking on exception thrown in SignalR hub? Visual Studio 2017上的Xamarin android模拟器不可用 - Xamarin android emulator on Visual Studio 2017 blacked out Xamarin传统Android项目在Visual Studio 2017上构建但出现错误 - Xamarin Traditional Android Project Build On Visual Studio 2017 But Have Error 将图像网址从SignalR集线器发送到javascript - Send image url to javascript from SignalR hub Azure Function - 从事件中心触发器发送消息到 Azure Z358E3E185C2A6EEE5539F - Azure Function - Send a message from an Event Hub Trigger to an Azure SignalR Service 在Android Xamarin Studio中从DialogFragment启动活动 - Start an Activity from DialogFragment in Android Xamarin Studio 如何使用 Visual Studio 和 xamarin 关闭 android 活动 - how to close activity android using visual studio and xamarin 断点在Visual Studio 2017中的xamarin uwp中不起作用 - Breakpoints not working in xamarin uwp in Visual Studio 2017
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM