赞
踩
里面加入了断线重连、心跳机制、退出释放资源,废话不多直接开干
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(); } }
上面的代码是我们公司的,所以我只截取了用到的部分,如果复制粘贴下来有用不到的地方直接删除即可
自取
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。