前一段時間,項目中需要用到webSocke,自己之前也沒有寫過,變相自己一時究竟;
本來以爲很難的一個東西可能會寫好久,沒想到非常簡單,看來是自己多慮了,okhttp已經給我們封裝好了WebSocket,我們直接去調用就可以了;
具體的就往下丟代碼吧;
首先
public interface IReceiveMessage {
void onConnectSuccess();// 連接成功
void onConnectFailed();// 連接失敗
void onClose(); // 關閉
void onMessage(String text);
}
此處需要我們的Activity去進行實現的類
然後,開始進行我們WebSocket的連接
public class WebSocketManager {
private final static String TAG = WebSocketManager.class.getSimpleName();
private final static int MAX_NUM = 5; // 最大重連數
private final static int MILLIS = 5000; // 重連間隔時間,毫秒
private volatile static WebSocketManager manager;
private OkHttpClient client;
private Request request;
private IReceiveMessage receiveMessage;
private WebSocket mWebSocket;
private boolean isConnect = false;
private int connectNum = 0;
private WebSocketManager() {
}
public static WebSocketManager getInstance() {
if (manager == null) {
synchronized (WebSocketManager.class) {
if (manager == null) {
manager = new WebSocketManager();
}
}
}
return manager;
}
public void init(String url, IReceiveMessage message) {
client = new OkHttpClient.Builder()
.writeTimeout(5, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.build();
request = new Request.Builder().url(url).build();
receiveMessage = message;
connect();
}
/**
* 連接
*/
public void connect() {
if (isConnect()) {
Log.i(TAG, "web socket connected");
return;
}
client.newWebSocket(request, createListener());
}
/**
* 重連
*/
public void reconnect() {
if (connectNum <= MAX_NUM) {
try {
Thread.sleep(MILLIS);
connect();
connectNum++;
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "reconnect over " + MAX_NUM + ",please check url or network");
}
}
/**
* 是否連接
*/
public boolean isConnect() {
return mWebSocket != null && isConnect;
}
/**
* 發送消息
*
* @param text 字符串
* @return boolean
*/
public boolean sendMessage(String text) {
if (!isConnect()) return false;
return mWebSocket.send(text);
}
/**
* 發送消息
*
* @param byteString 字符集
* @return boolean
*/
public boolean sendMessage(ByteString byteString) {
if (!isConnect()) return false;
return mWebSocket.send(byteString);
}
/**
* 關閉連接
*/
public void close() {
if (isConnect()) {
mWebSocket.cancel();
mWebSocket.close(1001, "客戶端主動關閉連接");
}
}
private WebSocketListener createListener() {
return new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, Response response) {
super.onOpen(webSocket, response);
Log.d(TAG, "open:" + response.toString());
mWebSocket = webSocket;
isConnect = response.code() == 101;
if (!isConnect) {
reconnect();
} else {
Log.i(TAG, "connect success.");
if (receiveMessage != null) {
receiveMessage.onConnectSuccess();
}
}
}
@Override
public void onMessage(WebSocket webSocket, String text) {
super.onMessage(webSocket, text);
if (receiveMessage != null) {
receiveMessage.onMessage(text);
}
}
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
super.onMessage(webSocket, bytes);
if (receiveMessage != null) {
receiveMessage.onMessage(bytes.base64());
}
}
@Override
public void onClosing(WebSocket webSocket, int code, String reason) {
super.onClosing(webSocket, code, reason);
mWebSocket = null;
isConnect = false;
if (receiveMessage != null) {
receiveMessage.onClose();
}
}
@Override
public void onClosed(WebSocket webSocket, int code, String reason) {
super.onClosed(webSocket, code, reason);
mWebSocket = null;
isConnect = false;
if (receiveMessage != null) {
receiveMessage.onClose();
}
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
super.onFailure(webSocket, t, response);
if (response != null) {
Log.i(TAG, "connect failed:" + response.message());
}
Log.i(TAG, "connect failed throwable:" + t.getMessage());
isConnect = false;
if (receiveMessage != null) {
receiveMessage.onConnectFailed();
}
reconnect();
}
};
}
最後就是我們的Acticity的實現
class MainActivity : AppCompatActivity(), IReceiveMessage {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_connect.setOnClickListener {
thread {
kotlin.run {
WebSocketManager.getInstance().init("這是寫我們的URL", this)
}
}
}
btn_client_send.setOnClickListener {
if (WebSocketManager.getInstance().sendMessage("客戶端發送")) {
addText("客戶端發送")
}
}
btn_client_close.setOnClickListener {
WebSocketManager.getInstance().close()
}
}
override fun onConnectSuccess() {
addText("連接成功\n")
}
override fun onConnectFailed() {
addText("連接失敗\n")
}
override fun onClose() {
addText("關閉成功\n")
}
override fun onMessage(text: String?) {
addText("接收消息:$text\n")
}
private fun addText(text: String?) {
runOnUiThread {
et_content.text.append(text)
}
}
override fun onDestroy() {
super.onDestroy()
WebSocketManager.getInstance().close()
}
攏共就這麼多的東西,頁面的佈局就不丟了,就一個連接,一個斷開連接的按鈕;android需要實現的webSocket的連接就這麼簡單;
其他的,可能有的童鞋需要做保活之類的,就可能需要去寫sevrce,播放無聲音樂,一像素,或者心跳包的東西了,具體的我也沒寫;就不多說了;