0

I'm attempting to convert the code located at How to use signalr in android Service from java to c# and have been making some progress. I'm now stuck at the final method. The java code is:

private void startSignalR() {
    Platform.loadPlatformComponent(new AndroidPlatformComponent());
    mInstance.setmHubConnection();
    mInstance.setHubProxy();
    ClientTransport clientTransport = new ServerSentEventsTransport(mInstance.mHubConnection.getLogger());
    SignalRFuture<Void> signalRFuture = mInstance.mHubConnection.start(clientTransport);

    try {
        signalRFuture.get();
    } catch (InterruptedException | ExecutionException e) {
        Log.e("SimpleSignalR", e.toString());
        return;
    }

    mInstance.sendMessage(MainActivity.unm,"Hello All!");

    String CLIENT_METHOD_BROADAST_MESSAGE = "recievedMessage";
    mInstance.mHubProxy.on(CLIENT_METHOD_BROADAST_MESSAGE,
            new SubscriptionHandler2<String,LoginInfo>() {
                @Override
                public void run(final String msg,final LoginInfo loginInfo) {
                    final String finalMsg = loginInfo.FullName  + "  says " + loginInfo.Password;
                Intent intent = new Intent();
                intent.setAction(MY_ACTION);
                intent.putExtra("DATAPASSED", finalMsg);
                sendBroadcast(intent);
            }
        }
        , String.class,LoginInfo.class);
}

Using a java to c# converter, this translated to:

    private void startSignalR()
    {
        Platform.loadPlatformComponent(new AndroidPlatformComponent());
        mInstance.setmHubConnection();
        mInstance.setHubProxy();
        ClientTransport clientTransport = new ServerSentEventsTransport(mInstance.mHubConnection.Logger);
        SignalRFuture<Void> signalRFuture = mInstance.mHubConnection.Start(clientTransport);

        try
        {
            signalRFuture.get();
        }
        catch (Exception e) when (e is InterruptedException || e is ExecutionException)
        {
            // Log.e("SimpleSignalR", e.ToString());
            return;
        }

        mInstance.sendMessage("", "Hello All!");

        string CLIENT_METHOD_BROADAST_MESSAGE = "recievedMessage";
        //String CLIENT_METHOD_BROADAST_MESSAGE = "messageReceived";
        mInstance.mHubProxy.on(CLIENT_METHOD_BROADAST_MESSAGE, new SubscriptionHandler2AnonymousInnerClass(this)
           , typeof(string), typeof(LoginInfo));
    }

    private class SubscriptionHandler2AnonymousInnerClass : SubscriptionHandler2<string, LoginInfo>
    {
        private readonly SignalRSrv outerInstance;

        public SubscriptionHandler2AnonymousInnerClass(SignalRSrv outerInstance)
        {
            this.outerInstance = outerInstance;
        }

        //JAVA TO C# CONVERTER WARNING: 'final' parameters are not available in .NET:
        //ORIGINAL LINE: @Override public void run(final String msg,final LoginInfo loginInfo)
        public override void run(string msg, LoginInfo loginInfo)
        {
            //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
            //ORIGINAL LINE: final String finalMsg = loginInfo.FullName + "  says " + loginInfo.Password;
            string finalMsg = loginInfo.FullName + "  says " + loginInfo.Password;
            Intent intent = new Intent();
            intent.Action = MY_ACTION;
            intent.PutExtra("DATAPASSED", finalMsg);
            sendBroadcast(intent);
        }
    }

This, of course, generated several errors in Visual Studio 2017.

First, the line Platform.loadPlatformComponent(new AndroidPlatformComponent()); generated the error Platform is inaccessible due to its protection level. Platform in Xamarin for Visual Studio 2017 is indeed protected and is a internal class in System and I cannot change this, so I'm at a loss as how to proceed with it. The same line generates the error The type or namespace name 'AndroidPlatformComponent' could not be found, these errors a numerous and not unexpected I just can't find an equivalent to AndroidPlatformComponent in Visual Studio 2017 so I'm at a loss as how to solve this one.

Next, on this line ClientTransport clientTransport = new ServerSentEventsTransport(mInstance.mHubConnection.Logger); generates the error The type or namespace name 'ClientTransport' could not be found, I was also unable to find an equivalent to this and again I'm at a loss as to proceed. Also on this line, .Logger is not defined for the hub connection, apparently it's .getLogger() in java, I was unable to find an equivalent for this one as well.

Next the line SignalRFuture<Void> signalRFuture = mInstance.mHubConnection.Start(clientTransport);' generates the error 1The type or namespace name 'SignalRFuture<>' could not be found, this seemes to be specific to SignalR, again, I am unable to find an equivalent.

The next one has me totally stumped, the line private class SubscriptionHandler2AnonymousInnerClass : SubscriptionHandler2<string, LoginInfo> generates the error The type or namespace name 'SubscriptionHandler2<,>' could not be found. I've looked everywhere online and read up on AnonymousInnerClass, but it was not help with this.

I'm hoping that the users here are more familiar with SignalR and the differences between c# functionality and java functionality. I'm not at all familiar with java nor am I familiar with SignalR and foreground services.

Prescott Chartier
  • 1,519
  • 3
  • 17
  • 34
  • From what I understand `Platform` shouldn't be a part of the system namespace!! – FreakyAli Jun 10 '19 at 06:19
  • I believe it isn't. I've been reading up on java so I can understand what's going on here and from what I've read I believe that the method is wiring up an event so it can pass the message back to the app. I'm moving forward with that premise and we'll see what happens. – Prescott Chartier Jun 10 '19 at 12:34
  • Can you tell me where did you get the SingalR dll from? – FreakyAli Jun 10 '19 at 13:55
  • SignalR is available on Nuget, there are two versions for .NET. Microsoft.AspNet.SignalR and Microsoft.AspNetCore.SignalR. I was unable to resolve issues with Microsoft.AspNetCore.Signalr and gave up on it but it is the current version of SignalR. Are you using Visual Studios? – Prescott Chartier Jun 10 '19 at 15:07
  • Can you try these blogs https://montemagno.com/real-time-communication-for-mobile-with-signalr/ or https://www.c-sharpcorner.com/article/xamarin-android-a-quick-demonstration-of-signalr/ and yes i have been using VS – FreakyAli Jun 11 '19 at 05:45
  • See my answer below. – Prescott Chartier Jun 11 '19 at 16:10
  • You might want to add the code that you wrote as well so that someone else who might have the same issue can find the solution – FreakyAli Jun 11 '19 at 20:06

1 Answers1

0

As it turns out, the last method in the java code I was converting was wiring up an event to pass the message received from the hub to the activity. In c# / Visual Studio (2017), that's done very differently which is why I didn't understand/recognize what was going on. So I created a handler in C# and execute a popup message for the message. This in itself may pose problems, but at least I know what's going on. This is the code I wrote to start SignalR from within the service and WireUp the handler:

    private void startSignalR()
    {
        // Company, Department, and section are private variables
        // their values are pulled from the intent bundle 
        // in the OnBind method, that code is:
        //     Bundle bundlee = intent.GetBundleExtra("TheBundle");
        //     MyUser = bundlee.GetParcelable("MyUser") as User;
        // This information is put into the bundle when the user is logged in.
        // I then pass that information to the SignalR client 
        // when I set the hub connection and placed on the querystring to the hub.

        mInstance.setmHubConnection(username, firstname,lastname,company,department,section);
        mInstance.setHubProxy();

        try
        {
            // Connect the client to the hup
            mInstance.mHubConnection.Start();
            // Set the event handler
            mInstance.WireUp();

        }
        catch (System.Exception e) when (e is InterruptedException || e is ExecutionException)
        {
            ShowMessage("Error: + e.Message)
        }
    }

This is the WireUp code, this is a method in the client code:

    public void WireUp()
    {
        // set the event handler
        mHubProxy.On("broadcastMessage", (string platform, string message) =>
        {
            if (OnMessageReceived != null)
                OnMessageReceived(this, string.Format("{0}: {1}", platform, message));
        });
    }

As I had anticipated, the popup message won't appear when the app is in the background, so I'm researching a workaround

Prescott Chartier
  • 1,519
  • 3
  • 17
  • 34