具有Android服务的Socket Io

Vol*_*pps 5 sockets service android threadpool background-task

美好的一天。考虑到Android的Socket IO库及其服务,我有一个非常具体的问题。

重要的是要提到我的设备是我正在测试的huawei p8 lite。

它在这里:

我有一个套接字Io库,该库正在我创建的服务中初始化

•我将侦听器设置为用于新消息的套接字io

•如果应用程序没有在用户进程中杀死,则一切工作都像字符。

•服务的目的是即使应用程序被杀死也保持套接字IO连接保持活动状态,以便向用户通知新消息。

•一旦应用程序被杀死,套接字IO连接即被断开

无论我尝试什么,我都会尝试所有可能的方法:隔离Service进程,为Service提供另一个进程,启动粘性,在服务销毁后立即重新创建它而不是粘性等等。

唯一有效的方法是startForeground()方法,但我不想使用它,因为它将遵循设计原则,而且我也不想显示有关正在运行的服务的任何通知。

我的问题是下一个:有人可以帮助我,告诉我即使应用程序被杀死了,我如何仍可以保持Socket IO连接的活动?

这是服务的代码。

package com.github.nkzawa.socketio.androidchat;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import java.net.URISyntaxException;

import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

public class SocketService extends Service {
    private Socket mSocket;
    public static final String TAG = SocketService.class.getSimpleName();

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "on created", Toast.LENGTH_SHORT).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "start command", Toast.LENGTH_SHORT).show();
        try {
            mSocket = IO.socket(Constants.CHAT_SERVER_URL);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
        mSocket.on("newMessageReceived", onNewMessage);
        mSocket.connect();
        return START_STICKY;
    }

    private Emitter.Listener onNewMessage = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            String message = args[0].toString();
            Log.d(TAG, "call: new message ");
            sendGeneralNotification(getApplicationContext(), "1", "new message", message, null);
        }
    };

    private void sendGeneralNotification(Context context, String uniqueId,
                                         String title, String contentText,
                                         @Nullable Class<?> resultClass) {

        NotificationManager notificationManagerCompat = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);

        android.support.v7.app.NotificationCompat.Builder builder = new android.support.v7.app.NotificationCompat.Builder(context);
        builder.setAutoCancel(true);


        builder.setContentTitle(title);
        builder.setContentText(contentText);
        builder.setGroup("faskfjasfa");
        builder.setDefaults(android.app.Notification.DEFAULT_ALL);
        builder.setStyle(new NotificationCompat.BigTextStyle()
                .setSummaryText(title)
                .setBigContentTitle(title)
                .bigText(contentText)
        );

        Intent requestsViewIntent = new Intent(context, MainActivity.class);
        requestsViewIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        requestsViewIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent requestsViewPending = PendingIntent.getActivity(context, Integer.valueOf(uniqueId), requestsViewIntent, 0);
        builder.setContentIntent(requestsViewPending);
        builder.setSmallIcon(R.drawable.ic_launcher);

        builder.setShowWhen(true);
        android.app.Notification notification = builder.build();
        notificationManagerCompat.notify(Integer.valueOf(uniqueId), notification);
    }

    private Notification getNotification() {
        Notification notification;
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setColor(getResources()
                .getColor(R.color.material_deep_teal_500))
                .setAutoCancel(true);

        notification = builder.build();
        notification.flags = Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_AUTO_CANCEL;

        return notification;
    }
}
Run Code Online (Sandbox Code Playgroud)

不,我既不想使用Firebase,也不想使用任何第三方创建的防火墙,因为我现在正在使用Firebase,而且我遭受延迟,未收到通知等问题的困扰,并且我将使自己的小方法变得更好。感谢大家的时间和耐心。

Ken*_*aga 3

在后台实现 Socket.io 并不是最好的主意。Socket.io 可以对您的服务器执行 ping 操作。短时间使用还可以,但在后台使用就不行了。

解决问题的最佳方法是结合 Socket.io 和FCM /GCM 主题来发出广播。在用户设备上,检测是否存在活动的 Socket.io 连接,如果退出则忽略 FCM,否则执行 FCM。