美文网首页
Android实现websocket长连接

Android实现websocket长连接

作者: SeekLife0 | 来源:发表于2023-01-21 15:18 被阅读0次

参考:
(61条消息) android接入简单的websocket步骤,建立一个长连接(带心跳检测)从服务器端接收消息_白马镇的少年的博客-CSDN博客_android websocket长连接

服务端:
springboot使用websocket创建长连接 - 简书 (jianshu.com)

代码
具体业务逻辑在接受消息的回调那里,需要修改代码中连接服务端的websocket地址。

package com.example.xy.service;

import android.app.Application;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.example.xy.BaseApp;
import com.example.xy.domain.MsgEventBean;
import com.example.xy.utils.AppSharedPreferences;
import com.example.xy.utils.Constant;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

public class BackService extends Service {

    public Application application;

    public Context context;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    private InitSocketThread thread;

    @Override
    public void onCreate() {
        super.onCreate();
        if (mWebSocket != null) {
            mWebSocket.close(1000, null);
        }
        new InitSocketThread().start();
        application= BaseApp.getApp();//这个是application,需要在功能清单里面的--android:name=".main.app.TzApplication"
        context=BaseApp.getApp();
        Log.e("TAG","onCreate------------*************-------------");
    }

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

    }

    /**
     * 心跳检测时间
     */
    private static final long HEART_BEAT_RATE = 10 * 1000;//每隔10秒进行一次对长连接的心跳检测


    private final String WEBSOCKET_HOST_AND_PORT = Constant.TEST_WEBSOCKET + "/webSocket/" + AppSharedPreferences.getInstance(context).getInt("userId");//可替换为自己的主机名和端口号
    private WebSocket mWebSocket;
    // 初始化socket

    private void initSocket() throws UnknownHostException, IOException {
        OkHttpClient client = new OkHttpClient.Builder().readTimeout(0, TimeUnit.MILLISECONDS).build();
        Request request = new Request.Builder().url(WEBSOCKET_HOST_AND_PORT).build();
        client.newWebSocket(request, new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {//开启长连接成功的回调
                super.onOpen(webSocket, response);
                mWebSocket = webSocket;
            }

            @Override
            public void onMessage(WebSocket webSocket, String text) {//接收消息的回调
                super.onMessage(webSocket, text);
                //收到服务器端传过来的消息text
                Log.e("TAG", "接收消息的回调--------------"+text);


                try {
                    //这个是解析你的回调数据
                    JSONObject jsonObject = JSON.parseObject(text);
                    //通过事件总线修改
                    String type = jsonObject.getString("type");
                    String title = jsonObject.getString("title");
                    String createTime = jsonObject.getString("createTime");
                    MsgEventBean bean = new MsgEventBean(); //自定义对象
                    switch (type){
                        case "1": //系统消息
                            bean.type = 1;
                            bean.content = title;
                            bean.time = createTime;
                            EventBus.getDefault().post(bean);
                            break;
                        case "2": //互动消息
                            bean.type = 2;
                            bean.content = title;
                            bean.time = createTime;
                            EventBus.getDefault().post(bean);
                            break;
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                super.onMessage(webSocket, bytes);
           
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                super.onClosing(webSocket, code, reason);
               
            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                super.onClosed(webSocket, code, reason);
               
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, @Nullable Response response) {//长连接连接失败的回调
                super.onFailure(webSocket, t, response);
           
              
            }
        });
        client.dispatcher().executorService().shutdown();
        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
    }


    class InitSocketThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                initSocket();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private long sendTime = 0L;
    // 发送心跳包
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                if(mWebSocket!=null) {
                    boolean isSuccess = mWebSocket.send("android-心跳");//发送一个消息给服务器,通过发送消息的成功失败来判断长连接的连接状态
                    if (!isSuccess) {//长连接已断开,
                        Log.e("TAG", "发送心跳包-------------长连接已断开");
                        mHandler.removeCallbacks(heartBeatRunnable);
                        mWebSocket.cancel();//取消掉以前的长连接
                        new InitSocketThread().start();//创建一个新的连接
                    } else {//长连接处于连接状态---
                        Log.e("TAG", "发送心跳包-------------长连接处于连接状态");
                    }
                }

                sendTime = System.currentTimeMillis();
            }
            mHandler.postDelayed(this, HEART_BEAT_RATE);//每隔一定的时间,对长连接进行一次心跳检测
        }
    };
    //关闭长连接
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mWebSocket != null) {
            mWebSocket.close(1000, null);
        }
    }

}

相关文章

网友评论

      本文标题:Android实现websocket长连接

      本文链接:https://www.haomeiwen.com/subject/feuhhdtx.html