前一段时间,项目中需要用到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,播放无声音乐,一像素,或者心跳包的东西了,具体的我也没写;就不多说了;