首先要說的是在app開發中,消息推送是必不可少的一個功能,方式有多種,現在簡單介紹一下我在項目開發中使用的方法,長連接
優點:開發成本低,數據安全,對於服務器壓力較小(相對輪詢)
缺點:耗電量高,容易被系統kill,需要一定的技術
使用okhttp和封裝的websocket包來實現
代碼貼出如下:
//長連接的建立
static OkHttpClient mOkHttpClient;
private void initWebSocket() {
mOkHttpClient = new OkHttpClient.Builder()
.readTimeout(3000, TimeUnit.SECONDS)//設置讀取超時時間
.writeTimeout(3000, TimeUnit.SECONDS)//設置寫的超時時間
.connectTimeout(3000, TimeUnit.SECONDS)//設置連接超時時間
.build();
Users users = null;
try {
users = MyApplication.db.selector(Users.class).findFirst();
} catch (DbException e) {
e.printStackTrace();
}
String url = null;
if (users != null) {
url = Constant.DB_URL + Constant.PORT + Constant.XHB_DIR + Constant.SEND_PERSONAL_NEWS + "?userId=" + users.getId(); //改成自已服務端的地址
}
Request request = new Request.Builder().url(url).build();
WebSocketCall webSocketCall = WebSocketCall.create(mOkHttpClient, request);
webSocketCall.enqueue(new WebSocketListener() {
private final ExecutorService sendExecutor = Executors.newSingleThreadExecutor();
private WebSocket webSocket;
@Override
public void onOpen(WebSocket webSocket, Response response) {
Log.d("WebSocketCall", "onOpen");
this.webSocket = webSocket;
}
/**
* 連接失敗
* @param e
* @param response Present when the failure is a direct result of the response (e.g., failed
* upgrade, non-101 response code, etc.). {@code null} otherwise.
*/
@Override
public void onFailure(IOException e, Response response) {
Log.d("WebSocketCall", "onFailure");
}
/**
* 接收到消息
* @param message
* @throws IOException
*/
@Override
public void onMessage(ResponseBody message) throws IOException {
final RequestBody response;
Log.d("WebSocketCall", "onMessage:" + message.source().readByteString().utf8());
String msg = message.source().readByteString().utf8();
NotificationResponse personalNewses = new Gson().fromJson(msg, NotificationResponse.class);
updatePersonalNewses(personalNewses);
//通知欄發送消息
if (personalNewses != null && personalNewses.getData() != null && personalNewses.getData().size() > 0) {
sendNotification(personalNewses.getData().get(0));
}
//通知remindFragment個人消息發生了變化
EventBus.getDefault().post(new MessageEvent("PersonalNewsUpdate"));
if (message.contentType() == WebSocket.TEXT) {//
response = RequestBody.create(WebSocket.TEXT, "你好");//文本格式發送消息
} else {
BufferedSource source = message.source();
Log.d("WebSocketCall", "onMessage:" + source.readByteString());
response = RequestBody.create(WebSocket.BINARY, source.readByteString());
}
message.source().close();
// sendExecutor.execute(new Runnable() {
// @Override
// public void run() {
// try {
// Thread.sleep(1000*60);
// webSocket.sendMessage(response);//發送消息
// } catch (IOException e) {
// e.printStackTrace(System.out);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// });
}
@Override
public void onPong(Buffer payload) {
Log.d("WebSocketCall", "onPong:");
}
/**
* 關閉
* @param code The <a href="http://tools.ietf.org/html/rfc6455#section-7.4.1">RFC-compliant</a>
* status code.
* @param reason Reason for close or an empty string.
*/
@Override
public void onClose(int code, String reason) {
sendExecutor.shutdown();
}
});
}
附上websocket包的鏈接,解壓後可直接使用