如何在Android Service中使用Signalr

我使用了信号器库,而为我创建的问题是,当电话进入睡眠状态时,它将发出连接超时错误,并且将不再连接至服务器.

in Activity

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


        startService(new Intent(getApplicationContext(), signalRService.class));
}}

in Service

public class SignalRService extends Service {

     private static String Tag = "ServiceSignalR";
     public static HubConnection conn = null;
     private static AndroidPlatformComponent androidPlatformComponent = null;
     private Thread back;

    private static Logger logger = new Logger() {

       @Override
       public void log(String message, LogLevel level) {
           Log.d(Tag, message);
       }
    };

    private Runnable m = new Runnable() {
       @Override
       public void run() {
            pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
            final PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.PARTIAL_WAKE_LOCK), "TAG");
            wakeLock.acquire();

           wm = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
           WifiManager.WifiLock lock =  wm.createWifiLock(WifiManager.WIFI_MODE_FULL, "LockTag");
           lock.acquire();

           startSignalR();

      }
   };

  @Override
  public void onCreate() {
     super.onCreate();
     Log.d(Tag, "Start Service");
     signalRService = this;
     back = new Thread(m);
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {

       back.start();

   networkChangeReceiver = new NetworkChangeReceiver() {
          @Override
        public void onReceive(Context context, Intent intent) {
               final ConnectivityManager connMgr = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);

               final NetworkInfo wifi = connMgr
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

               final NetworkInfo mobile = connMgr
                    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

               if (wifi.isAvailable() || mobile.isAvailable()) {
                if (isConnected(context)) {

                    if (back != null) {
                        if (back.isInterrupted()) {
                            back = null;
                            back = new Thread(m);
                            back.start();
                        }
                    }

                }
            }
        }
    };
        NetworkChangeReceiver.registerWifiReceiver(getApplicationContext(), networkChangeReceiver);
       return START_STICKY;
  }


   @Override
   public void onDestroy() {
       if (back != null)
          back.interrupt();
       super.onDestroy();
   }

  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
      return null;
  }


   public static void startSignalR() {
    // Connect to the server

      if (androidPlatformComponent == null)
            androidPlatformComponent = new AndroidPlatformComponent();

      Platform.loadPlatformComponent(androidPlatformComponent);


       if (conn == null)
           conn = new HubConnection("http://*************/", "", true, logger);

       HubProxy proxy = conn.createHubProxy("ChatHub");
       proxy.subscribe(new Object() {
        @SuppressWarnings("unused")
        public void messageReceived(String name, String message) {
            System.out.println(name + ": " + message);
        }
    });

     conn.start();

    conn.error(new ErrorCallback() {
        @Override
        public void one rror(Throwable throwable) {
            try {
                Thread.sleep(10000);
                conn = null;
                androidPlatformComponent = null;
                startSignalR();
            } catch (Exception ex) {
            }
        }
    });

    conn.received(new MessageReceivedHandler() {

        @Override
        public void onMessageReceived(JsonElement json) {
            Intent intent = new Intent("onReceiveMessage");
            intent.setAction("MessageAction");
            intent.putExtra("Message", json.toString());
            signalRService.sendBroadcast(intent);
        }
    });
   }


       @Override
       public void onTaskRemoved(Intent rootIntent) {
           if (android.os.Build.VERSION.SDK_INT >= 21) {          

               Intent restartServiceIntent = new  Intent(getApplicationContext(),
                SignalRService.class);
               restartServiceIntent.setPackage(getPackageName());

               PendingIntent restartServicePendingIntent = PendingIntent.getService(
                getApplicationContext(), 0, restartServiceIntent,
                PendingIntent.FLAG_ONE_SHOT);
               AlarmManager alarmService = (AlarmManager) getApplicationContext()
                .getSystemService(Context.ALARM_SERVICE);

              long thirtySecondsFromNow = 1000;
              alarmService.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow, restartServicePendingIntent);

              super.onTaskRemoved(rootIntent);
       }
   }
 }

in Manifests.xml

<?xml version="1.0" encoding="utf-8"?>
   <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="************.signalr2">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver android:name=".MyStartServiceReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>



    <service
        android:name=".SignalRService"
        android:enabled="true"
        android:exported="false"
        android:label="Sig"
        android:largeHeap="true"
        android:stopWithTask="false" />

    <receiver
        android:name=".BroadCastMessage"
        android:enabled="true">
        <intent-filter>
            <action android:name="MessageAction" />
        </intent-filter>
    </receiver>
    <receiver
        android:name=".NetworkChangeReceiver"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
    </receiver>
    <receiver
        android:name=".Screen"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_OFF" />
            <action android:name="android.intent.action.SCREEN_ON" />
        </intent-filter>
    </receiver>

</application>

in Boot BroadCast

public class MyStartServiceReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    context.stopService(new Intent(context.getApplicationContext() , SignalRService.class));
        context.startService(new Intent(context.getApplicationContext(), SignalRService.class));
}
}

in Message BroadCast

public class BroadCastMessage extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Log.d("Service" , "Message-----------------------------------------------------------------------");


    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("Hi")
            .setPriority(Notification.PRIORITY_MAX)
            .setCategory(Notification.CATEGORY_CALL)
            .setDefaults(Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_SOUND)
            .setContentText(intent.getStringExtra("Message") + "")
            .setAutoCancel(true)
            .setLights(Color.parseColor("red"), 2000, 1000);
    NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotifyMgr.notify(100, mBuilder.build());


  }
 }

in Network State BroadCast

public class NetworkChangeReceiver extends BroadcastReceiver {

private Boolean isConnected = false;

@Override
public void onReceive(final Context context, final Intent intent) {
    final ConnectivityManager connMgr = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);

    final NetworkInfo wifi = connMgr
            .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

    final NetworkInfo mobile = connMgr
            .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

    if (wifi.isAvailable() || mobile.isAvailable()) {
        if (isConnected(context)) {
            try {

                context.stopService(new Intent(context , SignalRService.class));
                context.startActivity(new Intent(context , SignalRService.class));
            } catch (Exception ex) {}
        }
    } else {
           //            isConnected = false;
    }
}


public static void registerWifiReceiver(Context context, BroadcastReceiver broadcastReceiver) {
    IntentFilter filter = new IntentFilter();
    filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    context.registerReceiver(broadcastReceiver, filter);
}

public static boolean isConnected(Context context) {

    boolean connectedState = isNetworkAvailable(context) || isWifiAvailable(context);

    return connectedState;
}

public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo mobileNetworkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
    return mobileNetworkInfo != null && mobileNetworkInfo.isConnected();

}

public static boolean isWifiAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo wifiNetworkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    return wifiNetworkInfo != null && wifiNetworkInfo.isConnected();
}
  }

解决方法:

是的你可以.首先,请确保SignalR服务正常运行,并记下令牌和集线器连接(组名),您可以通过调用这些组来从中订购这些呼叫.

1)参加一门单身课程

public class SignalRSingleton {

private static SignalRSingleton mInstance = null;
public HubConnection mHubConnection;
public HubProxy mHubProxy;

public static SignalRSingleton getInstance(){
    if(mInstance == null)
    {
        mInstance = new SignalRSingleton();
    }
    return mInstance;
}

public void setmHubConnection()
{
    String serverUrl = "http://192.168.1.5:8089/XM/";
    //String serverUrl = "http://192.168.1.184/test";
    mHubConnection = new HubConnection(serverUrl);
}

public void setHubProxy()
{
   /* Credentials credentials = new Credentials() {
        @Override
        public void prepareRequest(Request request) {
            request.addHeader("User-Name", MainActivity.unm);
        }
    };*/

    //mHubConnection.setCredentials(credentials);
    String SERVER_HUB_CHAT = "messages";
    //String SERVER_HUB_CHAT = "Chat";
    mHubProxy = mHubConnection.createHubProxy(SERVER_HUB_CHAT);
}


/**
 * method for clients (activities)
 */
public void sendMessage(String name , String message) {

    String str = "{'RequestMessage':{'PID':'lr1','Password':'GIefhSIC5iBCnxioufbwEw == '},'RequestType':'Login'}";
    String SERVER_METHOD_SEND = "getMessage";
    //String SERVER_METHOD_SEND = "Send";
    mHubProxy.invoke(SERVER_METHOD_SEND,str);
  }
}

2)然后实施服务

public class SignalRService extends Service {
    //private HubConnection mHubConnection;
    //private HubProxy mHubProxy;
    private Handler mHandler; // to display Toast message
    private final IBinder mBinder = new LocalBinder(); // Binder given to clients
    private SignalRSingleton mInstance;
    final static String MY_ACTION = "MY_ACTION";
    public SignalRService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = SignalRSingleton.getInstance();
        mHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int result = super.onStartCommand(intent, flags, startId);
        startSignalR();
        return result;
    }

    @Override
    public void onDestroy() {
        mInstance.mHubConnection.stop();
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Return the communication channel to the service.
        startSignalR();
        return mBinder;
    }

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        public SignalRService getService() {
            // Return this instance of SignalRService so clients can call public methods
            return SignalRService.this;
        }
    }


    /**
     * method for clients (activities)
     */


    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";
        //String CLIENT_METHOD_BROADAST_MESSAGE = "messageReceived";
        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);
    }
}

在您收到Service Hope的电话后,您将得到所需的东西.

上一篇:.net core 3.0 Signalr - 06 业务实现-业务分析


下一篇:c# – 使用SignalR时跟踪用户操作