微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Xamarin Forms Android 应用程序的 BackgroundService 中集成rabbitmq 客户端?

如何解决如何在 Xamarin Forms Android 应用程序的 BackgroundService 中集成rabbitmq 客户端?

Xamarin 表单应用

我的应用中有两个页面新闻公告在这页面上,我想显示从 rabbitmq 服务器收到的消息。

我在Android中实现了一个登录完成后执行的Service。 Shared Code 和 Android-Code 之间的通信是通过 Xamarin.MessagingCenter 实现的。

问题是我的 rabbitmq 客户端目前没有收到任何消息。

服务器在虚拟机上运行,​​应用在模拟器中运行。

代码

这是我的代码

Android 中的 DataTransferTaskService

[Service]
class DataTransferTaskService : Service
{
    static User user = new User { Groups = new List<string>() { "Test","Test2" } };
    CancellationTokenSource _cts;
    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override StartCommandResult OnStartCommand(Intent intent,StartCommandFlags flags,int startId)
    {
        // From shared code or in your PCL
        _cts = new CancellationTokenSource();

                PS();

        return StartCommandResult.NotSticky;
    }

    void PS()
    {
        var factory = new ConnectionFactory() { HostName = "10.0.0.3",UserName = "test",Password = "test",Port = 5672 };
        var connection = factory.CreateConnection();
        var channel = connection.CreateModel();
        
            channel.ExchangeDeclare(exchange: "Kastner",type: ExchangeType.Direct);

            var queueName = channel.QueueDeclare().QueueName;

            foreach (string g in user.Groups)
            {
                channel.QueueBind(queue: queueName,exchange: "Kastner",routingKey: g);
            }


            var consumer = new EventingBasicConsumer(channel);

            System.Diagnostics.Debug.WriteLine("vor event");
            consumer.Received += (model,ea) =>
            {
                var body = ea.Body.ToArray();
                var message = Encoding.UTF8.GetString(body);

                var obj = JObject.Parse(message);
                News n;
                Announcement a;
                System.Diagnostics.Debug.WriteLine("vor if");
                if (obj.Properties().Select(p => p.Name).FirstOrDefault() == "NewsId")
                {
                    n = JsonConvert.DeserializeObject<News>(message);
                    MessagingCenter.Send<object,News>(this,"NewsMessage",n);
                }
                else
                {
                    a = JsonConvert.DeserializeObject<Announcement>(message);
                    MessagingCenter.Send<object,Announcement>(this,"AnnouncementMessage",a);
                    
                }

            };
            channel.BasicConsume(queue: queueName,autoAck: true,consumer: consumer);

        
    }
}

Android 中的 MainActivity.cs

[Activity(Label = "DA_MessagebrokerApp",Icon = "@mipmap/icon",Theme = "@style/MainTheme",MainLauncher = true,ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);
        FFImageLoading.Forms.Platform.CachedImageRenderer.Init(enableFastRenderer: true);
        

        Xamarin.Essentials.Platform.Init(this,savedInstanceState);
        
        global::Xamarin.Forms.Forms.Init(this,savedInstanceState);
        CrossMediaManager.Current.Init(this);

        LoadApplication(new App());

        WireUpDataTransferTask();
    }
    public override void OnRequestPermissionsResult(int requestCode,string[] permissions,[GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode,permissions,grantResults);

        base.OnRequestPermissionsResult(requestCode,grantResults);
    }

    void WireUpDataTransferTask()
    {

        MessagingCenter.Subscribe<Newsviewmodel>(this,"StartDataTransferMessage",(sender) =>
        {
            var intent = new Intent(this,typeof(DataTransferTaskService));
            StartService(intent);
        });


    }
}

共享代码中的 Newsviewmodel

public class Newsviewmodel : Baseviewmodel
{
    static User user = new User { Groups = new List<string>() { "Test","Test2" } };
    private News _selectedItem;

    public ObservableCollection<News> Items { get; }
    public Command LoadItemsCommand { get; }
    public Command Additemcommand { get; }
    public Command<News> ItemTapped { get; }

    public Newsviewmodel()
    {
        Title = "News";
        Items = new ObservableCollection<News>();
        MessagingCenter.Subscribe<object,async (sender,arg) =>
        {
            await Task.Run(() =>DataStoreNews.AddItemAsync(arg));
            await ExecuteLoadItemsCommand();

        });
        MessagingCenter.Send<Newsviewmodel>(this,"StartDataTransferMessage");

        LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
        ItemTapped = new Command<News>(OnItemSelected);
    }

    void AddNewItem(News news)
    {
        if (!Items.Contains(news))
            Items.Add(news);
    }

    async Task ExecuteLoadItemsCommand()
    {
        IsBusy = true;

        try
        {
            Items.Clear();
            var items = await DataStoreNews.GetItemsAsync(true);
            foreach (var item in items)
            {
                Items.Add(item);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        finally
        {
            IsBusy = false;
        }
    }

    public void OnAppearing()
    {
        IsBusy = true;
        SelectedItem = null;
    }

    public News SelectedItem
    {
        get => _selectedItem;
        set
        {
            SetProperty(ref _selectedItem,value);
            OnItemSelected(value);
        }
    }


    async void OnItemSelected(News item)
    {
        if (item == null)
            return;

        // This will push the ItemDetailPage onto the navigation stack
        await Shell.Current.GoToAsync($"{nameof(NewsDetailPage)}?{nameof(NewsDetailviewmodel.NewsId)}={item.NewsId}");
    }

    
    
}

共享代码中的Baseviewmodel

public class Baseviewmodel : INotifyPropertyChanged
{
    public IDataStore<News> DataStoreNews => DependencyService.Get<IDataStore<News>>();
    public IDataStore<Announcement> DataStoreMessage => DependencyService.Get<IDataStore<Announcement>>();

    bool isBusy = false;
    public bool IsBusy
    {
        get { return isBusy; }
        set { SetProperty(ref isBusy,value); }
    }

    string title = string.Empty;
    public string Title
    {
        get { return title; }
        set { SetProperty(ref title,value); }
    }

    protected bool SetProperty<T>(ref T backingStore,T value,[CallerMemberName] string propertyName = "",Action onChanged = null)
    {
        if (EqualityComparer<T>.Default.Equals(backingStore,value))
            return false;

        backingStore = value;
        onChanged?.Invoke();
        OnPropertyChanged(propertyName);
        return true;
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        var changed = PropertyChanged;
        if (changed == null)
            return;

        changed.Invoke(this,new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

问题

Service Class中的PS()方法是我执行rabbitmq客户端代码方法。但是永远不会引发客户端收到消息的事件。我已经尝试过与另一个测试控制台应用程序的连接,并在那里收到了消息。我是否对服务做错了什么,或者为什么这不起作用?

编辑:我在 connection 类中删除channelDataTransferTaskService 的使用,因为我发现这些会导致一些问题,但仍然无法正常工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。