里面加入了断线重连、心跳机制、退出释放资源,废话不多直接开干
1.添加依赖
implementation "org.java-websocket:Java-WebSocket:1.5.1"
2、添加使用类
import android.util.Log;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URI;
import javax.net.ssl.SSLParameters;
public class JWebSocketClient extends WebSocketClient {
@Override
protected void onSetSSLParameters(SSLParameters sslParameters) {
//super.onSetSSLParameters(sslParameters);
}
public JWebSocketClient(URI serverUri) {
super(serverUri, new Draft_6455());
}
@Override
public void onOpen(ServerHandshake handshakedata) {
Log.e("JWebSocketClient", "onOpen()");
}
@Override
public void onMessage(String message) {
Log.e("JWebSocketClient", "onMessage()");
}
@Override
public void onClose(int code, String reason, boolean remote) {
Log.e("JWebSocketClient", "onClose()" + reason + "-****-" + remote);
}
@Override
public void onError(Exception ex) {
Log.e("JWebSocketClient", "onError()" + ex);
}
}
3、在代码中的使用
public class BloodSugarActivity extends BaseActivity {
String TAG="BloodSugarActivity";
public JWebSocketClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_blood_sugar);
}
@Override
protected void onResume() {
super.onResume();
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
if (client == null) {
Log.e(TAG, "``````````````````````onResume");
initWebSocket();
} else if (!client.isOpen()) {
reconnectWs();//进入页面发现断开开启重连
}
}
@Override
protected void onStop() {
super.onStop();
Log.e(TAG, "``````````````````````````````onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "`````````````````````````onDestroy");
closeConnect();
}
/**
* 初始化websocket
*/
public void initWebSocket() {
Log.e(TAG, "websocket的地址是:we://" + SpUtils.decodeString("websocketurl"));
URI uri = URI.create("ws://" + SpUtils.decodeString("websocketurl"));
//TODO 创建websocket
client = new JWebSocketClient(uri) {
@Override
public void onMessage(String message) {
super.onMessage(message);
if (!message.equals("Heartbeat")){
LogUtils(TAG, "websocket收到消息:" + message);
}
}
@Override
public void onOpen(ServerHandshake handshakedata) {
super.onOpen(handshakedata);
LogUtils(TAG, "websocket连接成功");
}
@Override
public void onError(Exception ex) {
super.onError(ex);
LogUtils(TAG, "websocket连接错误:" + ex);
}
@Override
public void onClose(int code, String reason, boolean remote) {
super.onClose(code, reason, remote);
if (code!=1000) {
reconnectWs();//意外断开马上重连
}
LogUtils(TAG, "websocket断开连接:·code:" + code + "·reason:" + reason + "·remote:" + remote);
}
};
//TODO 设置超时时间
client.setConnectionLostTimeout(110 * 1000);
//TODO 连接websocket
new Thread() {
@Override
public void run() {
try {
//connectBlocking多出一个等待操作,会先连接再发送,否则未连接发送会报错
client.connectBlocking();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 发送消息
*
* @param msg
*/
public void sendMsg(String msg) {
if (null != client) {
Log.e("", "^_^Websocket发送的消息:-----------------------------------^_^" + msg);
if (client.isOpen()) {
client.send(msg);
}
}
}
/**
* 开启重连
*/
private void reconnectWs() {
mHandler.removeCallbacks(heartBeatRunnable);
new Thread() {
@Override
public void run() {
try {
Log.e("开启重连", "");
client.reconnectBlocking();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 断开连接
*/
private void closeConnect() {
try {
//关闭websocket
if (null != client) {
client.close();
}
//停止心跳
if (mHandler != null) {
mHandler.removeCallbacksAndMessages(null);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
client = null;
}
}
// -------------------------------------websocket心跳检测------------------------------------------------
private static final long HEART_BEAT_RATE = 10 * 1000;//每隔10秒进行一次对长连接的心跳检测
private Handler mHandler = new Handler();
private Runnable heartBeatRunnable = new Runnable() {
@Override
public void run() {
if (client != null) {
if (client.isClosed()) {
Log.e("心跳包检测websocket连接状态1", client.isOpen() + "/" + SpUtils.decodeString("websocketurl"));
reconnectWs();//心跳机制发现断开开启重连
} else {
Log.e("心跳包检测websocket连接状态2", client.isOpen() + "/" + SpUtils.decodeString("websocketurl"));
sendMsg("Heartbeat");
}
} else {
Log.e("心跳包检测websocket连接状态重新连接", "");
//如果client已为空,重新初始化连接
client = null;
initSocketClient();
}
//每隔一定的时间,对长连接进行一次心跳检测
mHandler.postDelayed(this, HEART_BEAT_RATE);
}
};
}
自此就可以使用websocket了。。。
后续把配合service后台一起使用的方法写出来
下面是配合service后台一起使用的方法
这里是在service开启方法
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
import com.blankj.utilcode.util.ToastUtils;
import com.example.healthhut.R;
import com.example.healthhut.utils.SpMmvkUtils;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URI;
public class JWebSocketClientService extends Service {
public JWebSocketClient client;
private JWebSocketClientBinder mBinder = new JWebSocketClientBinder();
private final static int GRAY_SERVICE_ID = 1001;
//灰色保活
public static class GrayInnerService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(GRAY_SERVICE_ID, new Notification());
stopForeground(true);
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
PowerManager.WakeLock wakeLock;//锁屏唤醒
//获取电源锁,保持该服务在屏幕熄灭时仍然获取CPU时,保持运行
@SuppressLint("InvalidWakeLockTag")
private void acquireWakeLock() {
if (null == wakeLock) {
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "PostLocationService");
if (null != wakeLock) {
wakeLock.acquire();
}
}
}
//用于Activity和service通讯
public class JWebSocketClientBinder extends Binder {
public JWebSocketClientService getService() {
return JWebSocketClientService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
startForegroundService();
//初始化websocket
initSocketClient();
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//初始化websocket
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
acquireWakeLock();
return START_STICKY;
}
@Override
public void onDestroy() {
closeConnect();
super.onDestroy();
}
NotificationManager notificationManager;
String notificationId = "channelId";
String notificationName = "channelName";
private void startForegroundService() {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//创建NotificationChannel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(notificationId, notificationName, NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
}
}
private Notification getNotification() {
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("随访包服务")
.setContentText("随访包服务正在运行...");
//设置Notification的ChannelID,否则不能正常显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(notificationId);
}
Notification notification = builder.build();
return notification;
}
public JWebSocketClientService() {
}
/**
* 初始化websocket连接
*/
public void initSocketClient() {
URI uri;
uri = URI.create("ws://" + SpMmvkUtils.decodeString("websocketurl"));
Log.e("","连接的地址是************************:" + uri.toString());
client = new JWebSocketClient(uri) {
@Override
public void onMessage(String message) {
Log.e("","Service收到的消息:" + message);
Intent intent = new Intent();
intent.setAction("com.dhy.health.healthhut");
intent.putExtra("message", message);
intent.setPackage(getPackageName());
sendBroadcast(intent);
}
@Override
public void onOpen(ServerHandshake handshakedata) {
super.onOpen(handshakedata);
Log.e("","websocket连接成功");
ToastUtils.showLong(uri+"websocket连接成功");
mHandler.removeCallbacks(heartBeatRunnable);
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
if (null != client) {
Log.e("","第一次连接成功发送的消息:-----------------------------------" + "Heartbeat");
client.send("ok");
}
}
};
client.setConnectionLostTimeout(110*1000);
connect();
}
/**
* 连接websocket
*/
private void connect() {
new Thread() {
@Override
public void run() {
try {
//connectBlocking多出一个等待操作,会先连接再发送,否则未连接发送会报错
client.connectBlocking();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 发送消息
*
* @param msg
*/
public void sendMsg(String msg) {
if (null != client) {
if (client.isOpen()){
client.send(msg+"");
}else {
ToastUtils.showShort("重连中");
reconnectWs();
}
}else {
ToastUtils.showShort("重连中");
initSocketClient();
}
}
/**
* 断开连接
*/
public void closeConnect() {
try {
if (null != client) {
mHandler.removeCallbacks(heartBeatRunnable);
client.close();
client=null;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
client = null;
}
}
// -------------------------------------websocket心跳检测------------------------------------------------
private static final long HEART_BEAT_RATE = 10 * 1000;//每隔10秒进行一次对长连接的心跳检测
private Handler mHandler = new Handler();
private Runnable heartBeatRunnable = new Runnable() {
@Override
public void run() {
if (client != null) {
Log.e("心跳包检测websocket连接状态",client.isClosed()+"/" + SpMmvkUtils.decodeString("websocketurl"));
if (client.isClosed()) {
reconnectWs();
}
} else {
//如果client已为空,重新初始化连接
client = null;
initSocketClient();
}
//每隔一定的时间,对长连接进行一次心跳检测
mHandler.postDelayed(this, HEART_BEAT_RATE);
}
};
// -------------------------------------websocket心跳检测------------------------------------------------
private static final long HEART_BEAT_RATE2 = 110 * 1000;//每隔10秒进行一次对长连接的心跳检测
private Handler mHandler2 = new Handler();
private Runnable heartBeatRunnable2 = new Runnable() {
@Override
public void run() {
Log.e("","发送Heartbeat心跳包检测websocket连接状态"+"/" + SpMmvkUtils.decodeString("websocketurl"));
if (client != null) {
if (!client.isClosed()){
sendMsg("Heartbeat");
}else {
reconnectWs();
}
// sendMsg("Heartbeat");
} else {
//如果client已为空,重新初始化连接
client = null;
initSocketClient();
}
//每隔一定的时间,对长连接进行一次心跳检测
mHandler2.postDelayed(this, HEART_BEAT_RATE2);
}
};
/**
* 开启重连
*/
private void reconnectWs() {
mHandler.removeCallbacks(heartBeatRunnable);
new Thread() {
@Override
public void run() {
try {
Log.e( "开启重连","");
client.reconnectBlocking();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
在页面里面使用:
package com.dhy.health.healthhut.fragment;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.apkfuns.logutils.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.dhy.health.healthhut.R;
import com.dhy.health.healthhut.interFace.CommonValue;
import com.dhy.health.healthhut.interFace.IConstants;
import com.dhy.health.healthhut.utils.BLEFastUtils;
import com.dhy.health.healthhut.utils.Contast;
import com.dhy.health.healthhut.utils.MyNoPaddingTextView;
import com.dhy.health.healthhut.utils.StringUtil;
import com.dhy.health.healthhut.utils.ZHexUtil;
import com.dhy.health.healthhut.websocket.JWebSocketClient;
import com.dhy.health.healthhut.websocket.JWebSocketClientService;
import com.qmuiteam.qmui.widget.QMUIEmptyView;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import static android.content.Context.BIND_AUTO_CREATE;
/**
* Created by Forrest.
* User: Administrator
* Date: 2020/10/22
* Description: 页面
*/
public class TwFragment extends Fragment {
private Context mContext;
private JWebSocketClient client;
private JWebSocketClientService.JWebSocketClientBinder binder;
private JWebSocketClientService jWebSClientService;
private ChatMessageReceiver chatMessageReceiver;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
// LogUtils.tag(TAG).e("服务与活动成功绑定");
binder = (JWebSocketClientService.JWebSocketClientBinder) iBinder;
jWebSClientService = binder.getService();
client = jWebSClientService.client;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
LogUtils.tag(TAG).e("服务与活动成功断开");
Log.e("TAG","服务与活动成功断开");
}
};
private class ChatMessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("message");
LogUtils.tag(TAG).e(" 收到消息:" + message);
}
}
/**
* 绑定服务
*/
private void bindService() {
try {
Intent bindIntent = new Intent(mContext, JWebSocketClientService.class);
getActivity().bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);
} catch (Exception e) {
Log.e(TAG, "绑定服务异常");
}
}
/**
* 动态注册广播
*/
private void doRegisterReceiver() {
chatMessageReceiver = new ChatMessageReceiver();
IntentFilter filter = new IntentFilter("com.dhy.health.healthhut");
getActivity().registerReceiver(chatMessageReceiver, filter);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = View.inflate(getActivity(), R.layout.fragment_tw, null);
unbinder = ButterKnife.bind(this, view);
return view;
}
@Override
public void onResume() {
super.onResume();
mContext = getActivity();
//绑定服务
bindService();
doRegisterReceiver();
}
}
上面的代码是我们公司的,所以我只截取了用到的部分,如果复制粘贴下来有用不到的地方直接删除即可
自取