![JAR search and dependency download from the Maven repository](/logo.png)
com.avos.avoscloud.AVPushWebSocketClient Maven / Gradle / Ivy
The newest version!
package com.avos.avoscloud;
import android.net.SSLCertificateSocketFactory;
import android.net.SSLSessionCache;
import android.os.Build;
//import com.avos.avoscloud.java_websocket.WebSocket;
//import com.avos.avoscloud.java_websocket.client.WebSocketClient;
//import com.avos.avoscloud.java_websocket.drafts.Draft_17;
//import com.avos.avoscloud.java_websocket.framing.CloseFrame;
//import com.avos.avoscloud.java_websocket.framing.Framedata;
//import com.avos.avoscloud.java_websocket.framing.FramedataImpl1;
//import com.avos.avoscloud.java_websocket.handshake.ServerHandshake;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.extensions.IExtension;
import org.java_websocket.framing.Framedata;
import org.java_websocket.framing.PingFrame;
import org.java_websocket.handshake.ServerHandshake;
import org.java_websocket.protocols.IProtocol;
import org.java_websocket.protocols.Protocol;
import com.avos.avospush.session.CommandPacket;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.net.SocketFactory;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
/**
* Created by lbt05 on 5/20/16.
*/
public class AVPushWebSocketClient extends WebSocketClient {
public static final String SUB_PROTOCOL_2_1 = "lc.protobuf2.1";
public static final String SUB_PROTOCOL_2_3 = "lc.protobuf2.3";
private static final String HEADER_SUB_PROTOCOL = "Sec-WebSocket-Protocol";
private static final String HEADER_SNI_HOST = "Host";
private static final int PING_TIMEOUT_CODE = 3000;
private HeartBeatPolicy heartBeatPolicy;
private final long RECONNECT_INTERVAL = 10 * 1000;
Runnable reconnectTask = new Runnable() {
@Override
public void run() {
autoReconnect();
}
};
AVPacketParser receiver;
SSLSessionCache sessionCache;
private static ArrayList protocols = new ArrayList();
static {
protocols.add(new Protocol(SUB_PROTOCOL_2_3));
}
public AVPushWebSocketClient(URI serverURI, AVPacketParser parser,
final String subProtocol, boolean secEnabled) {
super(serverURI, new Draft_6455(Collections.emptyList(), protocols), new HashMap() {
{
put(HEADER_SUB_PROTOCOL, subProtocol);
}
}, 0);
if (AVOSCloud.isDebugLogEnabled()) {
LogUtil.avlog.d("trying to connect " + serverURI + ", subProtocol=" + subProtocol);
}
initHeartBeatPolicy();
if (secEnabled) {
setSocket();
}
this.receiver = parser;
}
private void initHeartBeatPolicy() {
heartBeatPolicy = new HeartBeatPolicy() {
@Override
public void onTimeOut() {
closeConnection(PING_TIMEOUT_CODE, "No response for ping");
}
@Override
public void sendPing() {
ping();
}
};
}
private void setSocket() {
try {
String url = getURI().toString();
if (!AVUtils.isBlankContent(url)) {
if (url.startsWith("wss")) {
if (null == sessionCache) {
sessionCache = new SSLSessionCache(AVOSCloud.applicationContext);
}
SSLCertificateSocketFactory socketFactory = (SSLCertificateSocketFactory)SSLCertificateSocketFactory.getDefault(5000, sessionCache);
Socket socket = socketFactory.createSocket();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
socketFactory.setUseSessionTickets(socket, true);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && socket instanceof SSLSocket) {
try {
SNIHostName serverName = new SNIHostName(getURI().getHost());
List serverNames = new ArrayList<>(1);
serverNames.add(serverName);
SSLParameters params = ((SSLSocket)socket).getSSLParameters();
params.setServerNames(serverNames);
((SSLSocket)socket).setSSLParameters(params);
} catch (Exception ex) {
ex.printStackTrace();
}
}
setSocket(socket);
} else {
SocketFactory socketFactory = SocketFactory.getDefault();
setSocket(socketFactory.createSocket());
}
}
} catch (Exception e) {
LogUtil.avlog.e("Socket Error", new AVException(e));
}
}
@Override
public void onOpen(ServerHandshake handshakedata) {
this.cancelReconnect();
heartBeatPolicy.startHeartbeat();
if (receiver != null) {
receiver.loginCmd();
receiver.processConnectionStatus(null);
receiver.processSessionsStatus(false);
}
LogUtil.avlog.d("onOpen()");
// resume livequery if necessary.
AVLiveQuery.resumeSubscribeers();
}
@Override
public void onMessage(ByteBuffer byteBuffer) {
if (receiver != null) {
receiver.processCommand(byteBuffer);
}
}
public void onMessage(String msg) {
}
@Override
public void onClose(int code, String reason, boolean remote) {
heartBeatPolicy.stopHeartbeat();
if (receiver != null) {
receiver.processSessionsStatus(true);
}
if (receiver != null) {
receiver.processConnectionStatus(new AVException(code, reason));
}
LogUtil.avlog.d("onClose(). local disconnection code=" + code + ", reason=" + reason + ", remote=" + remote);
switch (code) {
case -1:
LogUtil.avlog.d("connection refused");
if(remote){
if(receiver !=null){
receiver.processRemoteServerNotAvailable();
}
}else{
scheduleReconnect();
}
break;
case PING_TIMEOUT_CODE:
LogUtil.avlog.d("connection unhealthy");
autoReconnect();
break;
default:
scheduleReconnect();
break;
}
}
@Override
public void onError(Exception ex) {
ex.printStackTrace();
if (receiver != null && AVUtils.isConnected(AVOSCloud.applicationContext)) {
receiver.processRemoteServerNotAvailable();
}
}
protected void scheduleReconnect() {
if (RECONNECT_INTERVAL > 0) {
AVOSCloud.handler.postDelayed(reconnectTask, RECONNECT_INTERVAL);
}
}
protected void cancelReconnect() {
AVOSCloud.handler.removeCallbacks(this.reconnectTask);
}
AtomicBoolean destroyed = new AtomicBoolean(false);
protected void destroy(){
destroyed.set(true);
cancelReconnect();
heartBeatPolicy.stopHeartbeat();
LogUtil.avlog.d("connection destroyed");
}
protected boolean isDestroyed() {
return this.destroyed.get();
}
protected synchronized void autoReconnect() {
if (this.isConnecting() || this.isOpen()) {
// 已经是健康的状态了就没必要再发了
return;
} else if (AVUtils.isConnected(AVOSCloud.applicationContext)) {
this.reconnect();
} else if(!destroyed.get()){
// 网络状态有问题,我们延期再尝试吧
scheduleReconnect();
}
}
protected void ping() {
PingFrame frame = new PingFrame();
this.sendFrame(frame);
}
public void send(CommandPacket packet) {
if (AVOSCloud.isDebugLogEnabled()) {
LogUtil.avlog.d("uplink : " + packet.getGenericCommand().toString());
}
try {
send(packet.getGenericCommand().toByteArray());
} catch (Exception e) {
LogUtil.avlog.e(e.getMessage());
}
}
@Override
public void onWebsocketPong(WebSocket conn, Framedata f) {
super.onWebsocketPong(conn, f);
heartBeatPolicy.onPong();
}
public interface AVPacketParser {
void loginCmd();
void processCommand(ByteBuffer bytes);
void processConnectionStatus(AVException e);
void processRemoteServerNotAvailable();
void processSessionsStatus(boolean closeEvent);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy