1.首先需要在AndroidManifest.xml中开启一个服务:
<!-- 后台服务-长连接 -->
<service android:name=".service.BackService" />
2.添加引用
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
3.写一个类BackService继承Service:
public class BackService extends Service{
@Override
public void onCreate() {
super.onCreate();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
4.在BackService的onCreate()方法中开启一个线程:
@Override
public void onCreate() {
super.onCreate();
new InitSocketThread().start();
}
class InitSocketThread extends Thread {
@Override
public void run() {
super.run();
try {
initSocket();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 心跳检测时间
*/
private static final long HEART_BEAT_RATE = 15 * 1000;//每隔15秒进行一次对长连接的心跳检测
private static final String WEBSOCKET_HOST_AND_PORT = "ws://xxx:9501";//可替换为自己的主机名和端口号
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
}
@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);//开启心跳检测
}
5.开启心跳检测:
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) {
boolean isSuccess = mWebSocket.send("");//发送一个空消息给服务器,通过发送消息的成功失败来判断长连接的连接状态
if (!isSuccess) {
//长连接已断开
mHandler.removeCallbacks(heartBeatRunnable);
mWebSocket.cancel();//取消掉以前的长连接
new InitSocketThread().start();//创建一个新的连接
} else {
//长连接处于连接状态
}
sendTime = System.currentTimeMillis();
}
mHandler.postDelayed(this, HEART_BEAT_RATE);//每隔一定的时间,对长连接进行一次心跳检测
}
};
6.当BackService关闭时,关闭掉长连接:
@Override
public void onDestroy() {
super.onDestroy();
if (mWebSocket != null) {
mWebSocket.close(1000, null);
}
}
7.BackService类完整代码
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.example.mytest.application.BaseApplication;
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;
/**
* 心跳检测时间
*/
private static final long HEART_BEAT_RATE = 15 * 1000;//每隔15秒进行一次对长连接的心跳检测
private static final String WEBSOCKET_HOST_AND_PORT = "ws://172.20.13.91:8004/websocket/";//可替换为自己的主机名和端口号
private WebSocket mWebSocket;
@Override
public void onCreate() {
super.onCreate();
if (mWebSocket != null) {
mWebSocket.close(1000, null);
}
new InitSocketThread().start();
//application= BaseApplication.getApplication();//这个是application,需要在功能清单里面的--android:name=".main.app.TzApplication"
//context=BaseApplication.getApplication();
Log.e("TAG","onCreate------------*************-------------");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
if (mWebSocket != null){
mWebSocket.close(1000,null);
}
}
public class InitSocketThread extends Thread {
@Override
public void run() {
super.run();
try {
initSocket();
} catch (IOException e) {
e.printStackTrace();
}
}
// 初始化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);
}
@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);//开启心跳检测
}
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) {
boolean isSuccess = mWebSocket.send("");//发送一个空消息给服务器,通过发送消息的成功失败来判断长连接的连接状态
if (!isSuccess) {
//长连接已断开
mHandler.removeCallbacks(heartBeatRunnable);
mWebSocket.cancel();//取消掉以前的长连接
new com.example.mytest.websocket.thread.InitSocketThread().start();//创建一个新的连接
} else {
//长连接处于连接状态
//长连接处于连接状态---
Log.e("TAG", "发送心跳包-------------长连接处于连接状态");
}
sendTime = System.currentTimeMillis();
}
mHandler.postDelayed(this, HEART_BEAT_RATE);//每隔一定的时间,对长连接进行一次心跳检测
}
};
}
}
8.在你想要长连接的地方连接
public class TestActivity extends AppCompatActivity {
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
initView();
}
private void initView() {
findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
start();
}
});
findViewById(R.id.btn_stop).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stop();
}
});
}
private void start() {
intent = new Intent(TestActivity.this, BackService.class);
startService(intent);
Log.e("TAG", "start----");
}
private void stop() {
stopService(intent);
Log.e("TAG", "stop----");
}
}
9.websocket客户端测试工具
websocket客户端测试工具