Android推送SDK(9)-TCP网络问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android推送SDK(9)-TCP网络问题相关的知识,希望对你有一定的参考价值。

参考技术A 主目录见: android高级进阶知识(这是总目录索引)
[written by 无心追求 ]



把Http和TCP连接服务做区分导致IM的TCP使用80端口连接进来的时候被误

识别成是一个Http请求,所以就对IM的TCP数据流(TLV格式)进行解析导

致报错返回了一个Http请求报错的网页的html数据,具体返回的数据格式

客户端打印是:

以上是客户端TCP数据流read到100字节打印出来的数据,是一个Http请求

失败返回Http状态码为400的网页Html数据

以上是tcpdump抓包信息,从抓包信息中可以得知返回的数据确实是一个

Http请求失败的网页,对比客户端程序log打印是吻合的

式的数据,所以对read到的数据进行常规的TLV数据解析导致程序解析报错

(数组越界):

客户端发生数据解析报错之后会认为当前接收到的数据已经不正确,同时

也会认为后面接续读取的数据也将不正确,所以会把socket连接关闭重连



应该下调心跳周期,但是旧版(1.0.1Realease-1.0.6Realease版本)存在

不足,并没有对此做过滤处理,所以会不断的下调心跳

断线后会马上重连

接断开的域名和端口再次尝试重连,在重试重连失败的时候才会去切换域

名或者端口,而遇到这种情况,每次尝试重连TCP都能连接成功,连接成功

之后,数据解析失败又把TCP连接断开,然后再拿原来的域名和端口,再重

连,再断开,如此陷入死循环,无法切换域名或者端口,断线重连频率很

高:

TCP连接IM服务器gw.im.okii.com成功,连接端口为80

入的TCP数据为323个字节

的数据进行解析

srcPos=2 dst.length=121 dstPos=0 length=121表示数据解析报错,数组

越界

误的识别成Http短连接

不下调心跳间隔,避免心跳误下调,影响心跳探测的准确性

时间间隔递增重连,避免频繁的重连

一些常用的端口,例如8080,443,1000一下的端口等都不能使用,避免出

现类似的问题

和端口去再次连接IM服务器导致无法跳出这个域名和端口连接造成的异常

,如果客户端有成功切换域名或者端口,那么遇到上述情况会立即切换到

8000端口,次数连接就会恢复正常

有上传大数据的手表分析来看全部都恢复正常使用

111.44.228.186这个地址(正确的应该是106.75.86.52),而被误识别成

Http短链接,然后返回一个错误的网页html数据,然后客户端接收到数据

后解析报错,导致频繁的断线重连和心跳下调

跳误下调,重连频繁,与香港的原因类似

gw.im.okii.com本地dns解析出来的ip为111.44.228.186,由此确认是被劫

持了

客户端对接收到的TCP数据解析异常ArrayIndexOutOfBoundsException,数

组越界

客户端在数据解析异常后断线

连接断开后心跳下调

推送通知未在Android 8.0中使用解析sdk显示

我正在开发Android应用程序,我在自定义Parse推送通知类中注册了FCM推送通知。从Parse Dashboard发送Push时,它会进入我的Receiver,但不会显示在我的屏幕的Notification Bar中。我的自定义类以及清单和代码如下所示。我也搜索了许多类似的问题,但没有运气。

我的清单:

<receiver android:name="com.parse.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.kolbeh" />
            </intent-filter>
        </receiver>
        <meta-data android:name="com.parse.push.gcm_sender_id"
            android:value="id:854901#####" />

        <service android:name="com.parse.PushService" />

        <receiver
            android:name="dinewhere.fcm.CustomPushReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.OPEN" />
                <action android:name="com.parse.push.intent.DELETE" />
            </intent-filter>
        </receiver>

我的自定义接收器:

public class CustomPushReceiver extends ParsePushBroadcastReceiver {
    private final String TAG = CustomPushReceiver.class.getSimpleName();

    private NotificationUtils notificationUtils;

    private Intent parseIntent;

    public CustomPushReceiver() {
        super();
    }

    @Override
    protected void onPushReceive(Context context, Intent intent) {
        //super.onPushReceive(context, intent);

        if (intent == null)
            return;

        try {
            JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));

            Log.e(TAG, "Push received: " + json);

            parseIntent = intent;

            parsePushJson(context, json);

        } catch (JSONException e) {
            Log.e(TAG, "Push message json exception: " + e.getMessage());
        }
    }

    @Override
    protected void onPushDismiss(Context context, Intent intent) {
        super.onPushDismiss(context, intent);
    }

    @Override
    protected void onPushOpen(Context context, Intent intent) {
        super.onPushOpen(context, intent);
        System.out.println("asdf");
    }

    /**
     * Parses the push notification json
     *
     * @param context
     * @param json
     */
    private void parsePushJson(Context context, JSONObject json) {
        try {
            String message = json.getString("alert");

            Intent resultIntent = new Intent(context, MainActivity.class);
            resultIntent.putExtra("Chat", true);
            showNotificationMessage(context, "Hello", message, resultIntent);

        } catch (JSONException e) {
            Log.e(TAG, "Push message json exception: " + e.getMessage());
        }
    }


    /**
     * Shows the notification message in the notification bar
     * If the app is in background, launches the app
     *
     * @param context
     * @param title
     * @param message
     * @param intent
     */
    private void showNotificationMessage(Context context, String title, String message, Intent intent) {

        notificationUtils = new NotificationUtils(context);

        intent.putExtras(parseIntent.getExtras());

        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        notificationUtils.showNotificationMessage(title, message, intent);
    }
}

我的节目通知消息方法:

 public void showNotificationMessage(String title, String message, Intent intent) {

        // Check for empty push message
        if (TextUtils.isEmpty(message))
            return;

        if (airportAssistUtil.isAppIsInBackground(mContext)) {
            // notification icon
            int icon = R.mipmap.ic_launcher_round;



            PendingIntent resultPendingIntent =
                    PendingIntent.getActivity(
                            mContext,
                            0,
                            intent,
                            PendingIntent.FLAG_CANCEL_CURRENT
                    );

            NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();

            PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

            NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                    mContext);
            Notification notification = mBuilder.setSmallIcon(icon).setTicker("Kolbeh").setWhen(0)
                    .setAutoCancel(true)
                    .setStyle(inboxStyle)
                    .setContentTitle("Kolbeh")
                    .setContentIntent(resultPendingIntent)
                    .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                    .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
                    .setContentText(message)
                    .build();

            mBuilder.setContentIntent(contentIntent);

            NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(count++, notification);
        } 
    }
答案

如果您的应用定位到Android O.那么您必须显示带通知频道的通知。来自android O每个通知必须包含在渠道Read here内。

以上是关于Android推送SDK(9)-TCP网络问题的主要内容,如果未能解决你的问题,请参考以下文章

android 进阶

使用 SDK 为 Android 设置 Salesforce 推送通知

使用 Quickblox SDK 未收到从 iOS 到 android 的推送通知

有哪位大虾用百度云推送的 Python sdk 做过 iOS 推送吗

怎样下载Android SDK

android项目它得到一些与AN​​DROID_SDK_HOME相关的错误