使用java-webSocket开源库
第一步:添加依赖
//webSocket
implementation "org.java-websocket:Java-WebSocket:1.5.1"
第二步:创建一个绑定服务
要发送消息需要调用WebSocketClient的send方法,它是写在我们的service中,所以需要BindService来实现。
public class WebSocketService extends Service {
private static final String TAG = "WebSocketService";
private static final long HEART_BEAT_RATE = 5 * 1000;//每隔5秒进行一次对长连接的心跳检测
private final HeartHandler mHeartHandler = new HeartHandler(this);
private WebSocketClient client;
private ServiceBinder binder = new ServiceBinder();
private String roomId;
private String userId;
private Messenger mMessenger;
@Nullable
@Override
public IBinder onBind(Intent intent) {
roomId = intent.getStringExtra("roomId");
userId = intent.getStringExtra("userId");
if (mMessenger == null) {
mMessenger = (Messenger)intent.getExtras().get("handler");
}
initSocketClient();
return this.binder;
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: ");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
try {
Log.d(TAG, "onDestroy: socket service onDestroy()");
client.close();
mHeartHandler.removeCallbacksAndMessages(null);
} catch (Exception e) {
e.printStackTrace();
}
}
public final class ServiceBinder extends Binder {
public WebSocketService getService() {
return WebSocketService.this;
}
}
/**
* 初始化webSocket
*/
public void initSocketClient(){
//TODO webSocket地址
String webSocketUrl = "ws://...";
try {
Log.d(TAG, "initSocketClient: roomId---" + roomId);
client = new WebSocketClient(new URI(webSocketUrl + roomId + "/" + userId),new Draft_6455()) {
@Override
public void onWebsocketPong(WebSocket conn, Framedata f) {
super.onWebsocketPong(conn, f);
Log.d(TAG, "onWebsocketPong: " + f.getPayloadData().toString());
Log.d(TAG, "onWebsocketPong: socket ping" + f.getOpcode());
}
@Override
public void onOpen(ServerHandshake handshakedata) {
// 连接打开以后的回调
Log.d(TAG, "onOpen: ");
}
@Override
public void onMessage(String message) {
// 收到消息的回调
Log.d(TAG, "onMessage: socket接收服务器发来的消息:" + message);
Message handlerMessage = Message.obtain();
handlerMessage.what = HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS;
handlerMessage.obj = message;
try {
mMessenger.send(handlerMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onError(Exception ex) {
// 连接出错的回调
Log.d(TAG, "onError: " + ex);
reconnectWs();
}
@Override
public void onClose(int code, String reason, boolean remote) {
// 连接关闭的回调, remote如果为true表示被服务端cut掉了
Log.d(TAG, "onClose: ");
reconnectWs();
}
@Override
public void onMessage(ByteBuffer bytes) {
super.onMessage(bytes);
Log.d(TAG, "onMessage: socket bytebuffer bytes---" + bytes);
}
@Override
protected void onSetSSLParameters(SSLParameters sslParameters) {
// super.onSetSSLParameters(sslParameters);
try{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
super.onSetSSLParameters(sslParameters);
}
}catch(Exception e) {
e.printStackTrace();
}
}
};
mHeartHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
client.connectBlocking();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通过webSocket发送消息
* @param sMessage
*/
public void sendMessage(String sMessage){
if (client == null || client.isClosed()) {
Log.d(TAG, "sendMessage: client is null or closed");
return;
}
try {
client.send(sMessage);
Log.d(TAG, "sendMessage: 发送---" + sMessage);
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* 静态内部类Handler
*/
private static class HeartHandler extends Handler {
private final WeakReference<WebSocketService> mService;
public HeartHandler(WebSocketService service) {
this.mService = new WeakReference<>(service);
}
@Override
public void handleMessage(@NonNull Message msg) {
WebSocketService webSocketService = mService.get();
if (webSocketService!=null) {
}
}
}
//心跳线程
private final Runnable heartBeatRunnable = new Runnable() {
@Override
public void run() {
Log.d(TAG, "run: 扑通");
if (client != null) {
if (client.isClosed()) {
reconnectWebSocket();
return;
}
} else {
//如果client已为空,重新初始化websocket
initSocketClient();
return;
}
//定时对长连接进行心跳检测
mHeartHandler.postDelayed(this, HEART_BEAT_RATE);
}
};
/**
* 开启重连
*/
private void reconnectWs() {
mHandler.removeCallbacks(heartBeatRunnable);
try {
//重连
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
client.reconnectBlocking();
Log.d(TAG, "run: reconnectWs---心跳重连");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.1:Service的onBind
@Override
public IBinder onBind(Intent intent) {
roomId = intent.getStringExtra("roomId");
userId = intent.getStringExtra("userId");
if (mMessenger == null) {
mMessenger = (Messenger)intent.getExtras().get("handler");
}
return this.binder;
}
intent中是从Activity传递过来的参数,创建WebSocketClient的时候需要roomId,和userId,roomId相同的用户会进入同一个webSocket房间,发送的消息互相能接收,userId用来区分不同的用户。
Messenger用于接收从Activity传递过来的Handledr
2.2 连接webSocket服务(进入webSocket房间)
/**
* 初始化webSocket
*/
public void initSocketClient(){
//TODO webSocket地址
String webSocketUrl = "ws://...";
try {
Log.d(TAG, "initSocketClient: roomId---" + roomId);
client = new WebSocketClient(new URI(webSocketUrl + roomId + "/" + userId),new Draft_6455()) {
@Override
public void onWebsocketPong(WebSocket conn, Framedata f) {
super.onWebsocketPong(conn, f);
Log.d(TAG, "onWebsocketPong: " + f.getPayloadData().toString());
Log.d(TAG, "onWebsocketPong: socket ping" + f.getOpcode());
}
@Override
public void onOpen(ServerHandshake handshakedata) {
// 连接打开以后的回调
Log.d(TAG, "onOpen: ");
}
@Override
public void onMessage(String message) {
// 收到消息的回调
Log.d(TAG, "onMessage: socket接收服务器发来的消息:" + message);
Message handlerMessage = Message.obtain();
handlerMessage.what = HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS;
handlerMessage.obj = message;
try {
mMessenger.send(handlerMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onError(Exception ex) {
// 连接出错的回调
Log.d(TAG, "onError: " + ex);
reconnectWebSocket();
}
@Override
public void onClose(int code, String reason, boolean remote) {
// 连接关闭的回调, remote如果为true表示被服务端cut掉了
Log.d(TAG, "onClose: ");
if (remote) {
Log.d(TAG, "onClose: 服务器cut");
reconnectWebSocket();
}
}
@Override
public void onMessage(ByteBuffer bytes) {
super.onMessage(bytes);
Log.d(TAG, "onMessage: socket bytebuffer bytes---" + bytes);
}
@Override
protected void onSetSSLParameters(SSLParameters sslParameters) {
// super.onSetSSLParameters(sslParameters);
try{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
super.onSetSSLParameters(sslParameters);
}
}catch(Exception e) {
e.printStackTrace();
}
}
};
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
client.connectBlocking();
} catch (Exception e) {
e.printStackTrace();
}
}
2.3开启心跳
onOpen表示连接成功,此时需要开启心跳不断检测连接,防止中途断连
private static final long HEART_BEAT_RATE = 5 * 1000;//每隔5秒进行一次对长连接的心跳检测
private final HeartHandler mHeartHandler = new HeartHandler(this);
/**
* 静态内部类Handler
*/
private static class HeartHandler extends Handler {
private final WeakReference<WebSocketService> mService;
public HeartHandler(WebSocketService service) {
this.mService = new WeakReference<>(service);
}
@Override
public void handleMessage(@NonNull Message msg) {
WebSocketService webSocketService = mService.get();
if (webSocketService!=null) {
}
}
}
//心跳线程
private final Runnable heartBeatRunnable = new Runnable() {
@Override
public void run() {
Log.d(TAG, "run: 扑通");
if (client != null) {
if (client.isClosed()) {
reconnectWebSocket();
return;
}
} else {
//如果client已为空,重新初始化websocket
initSocketClient();
return;
}
//定时对长连接进行心跳检测
mHeartHandler.postDelayed(this, HEART_BEAT_RATE);
}
};
2.4接收消息
onMessage表示接收到消息,可以把消息传递到Activity
@Override
public void onMessage(String message) {
// 收到消息的回调
Log.d(TAG, "onMessage: socket接收服务器发来的消息:" + message);
Message handlerMessage = Message.obtain();
handlerMessage.what = HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS;
handlerMessage.obj = message;
try {
mMessenger.send(handlerMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
}
第三步:在Activity中绑定服务,开启webSocket
public class WebSocketActivity extends AppCompatActivity {
private static final String TAG = "WebSocketActivity";
private final WebSocketHandler mHandler = new WebSocketHandler(this);
private WebSocketService socketService;
private ServiceConnection serviceConnection;
private TextView tvState;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_socket);
tvState = findViewById(R.id.act_webSocket_tv_state);
openSocket();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (serviceConnection!=null) {
unbindService(serviceConnection);
}
}
/**
* 开启webSocket接收服务端的事件推送
*/
private void openSocket() {
Intent socketInten = new Intent(this, WebSocketService.class);
socketInten.putExtra("roomId", "111");
socketInten.putExtra("userId", "222");
socketInten.putExtra("handler",new Messenger(mHandler));
try {
serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
WebSocketService.ServiceBinder binder = (WebSocketService.ServiceBinder) service;
socketService = binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected: ");
}
};
this.bindService(socketInten, serviceConnection, Service.BIND_AUTO_CREATE);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发送webSocket消息
*/
private void sendMessage(String message) {
socketService.sendMessage(message);
}
/**
* 静态内部类Handler
* 接收Service消息
*/
private static class WebSocketHandler extends Handler {
private final WeakReference<WebSocketActivity> mActivity;
public WebSocketHandler(WebSocketActivity activity) {
this.mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(@NonNull Message msg) {
WebSocketActivity activity = mActivity.get();
if (activity!=null) {
switch (msg.what) {
case HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS:
activity.tvState.setText(msg.obj.toString());
break;
default:
break;
}
}
}
}
}
第四步:发送消息
在Activity中调用sendMessage方法,传入String类型消息(封装成json),然后通过service中的sendMessage方法,调用WebSocketClient.send()
WebSocketActivity:---------------------
/**
* 发送webSocket消息
*/
private void sendMessage(String message) {
socketService.sendMessage(message);
}
WebSocketService:----------------------
/**
* 通过webSocket发送消息
* @param sMessage
*/
public void sendMessage(String sMessage){
if (client == null || client.isClosed()) {
Log.d(TAG, "sendMessage: client is null or closed");
return;
}
try {
client.send(sMessage);
Log.d(TAG, "sendMessage: 发送---" + sMessage);
}catch (Exception e) {
e.printStackTrace();
}
}
第五步:处理接收到的消息
/**
* 静态内部类Handler
* 接收Service消息
*/
private static class WebSocketHandler extends Handler {
private final WeakReference<WebSocketActivity> mActivity;
public WebSocketHandler(WebSocketActivity activity) {
this.mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(@NonNull Message msg) {
WebSocketActivity activity = mActivity.get();
if (activity!=null) {
switch (msg.what) {
case HandlerMessageWhat.CONNECT_WEB_SOCKET_SUCCESS:
activity.tvState.setText(msg.obj.toString());
break;
default:
break;
}
}
}
}
该Handler是通过Intent将实例传递到Service,在Service中由Messenger接收,然后在webSocket的onMessage回调中通过Messenger将消息发送到Activity中的handleMessage方法。
demo资源地址: