美文网首页
Android OkHttp3 WebSocket

Android OkHttp3 WebSocket

作者: lesliefang | 来源:发表于2020-04-23 16:45 被阅读0次

    websocket 给人的印象就是使用非常简单,比原生Socket像 Netty 等简单很多。无论服务端还是客户端都很简单

    OkHttp3 也是支持WebSocket的,因为 android 网络请求基本都用OkHttp3,所以没必要引入其他的框架了。

    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.Handler;
    import android.os.IBinder;
    import android.util.Log;
    
    import androidx.annotation.Nullable;
    
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    import okhttp3.WebSocket;
    import okhttp3.WebSocketListener;
    
    public class WebSocketService extends Service {
        private static final String TAG = "websocket";
        private static final String WS = "ws://121.40.165.18:8800";
    
        private WebSocket webSocket;
        private WebSocketCallback webSocketCallback;
        private int reconnectTimeout = 5000;
        private boolean connected = false;
    
        private Handler handler = new Handler();
    
        class LocalBinder extends Binder {
            WebSocketService getService() {
                return WebSocketService.this;
            }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new LocalBinder();
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            webSocket = connect();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return START_STICKY;
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            if (webSocket != null) {
                close();
            }
        }
    
        private WebSocket connect() {
            Log.d(TAG, "connect " + WS);
            OkHttpClient client = new OkHttpClient.Builder().build();
            Request request = new Request.Builder().url(WS).build();
            return client.newWebSocket(request, new WebSocketHandler());
        }
    
        public void send(String text) {
            Log.d(TAG, "send " + text);
            if (webSocket != null) {
                webSocket.send(text);
            }
        }
    
        public void close() {
            if (webSocket != null) {
                boolean shutDownFlag = webSocket.close(1000, "manual close");
                Log.d(TAG, "shutDownFlag " + shutDownFlag);
                webSocket = null;
            }
        }
    
        private void reconnect() {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, "reconnect...");
                    if (!connected) {
                        connect();
                        handler.postDelayed(this, reconnectTimeout);
                    }
                }
            }, reconnectTimeout);
        }
    
        private class WebSocketHandler extends WebSocketListener {
    
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                Log.d(TAG, "onOpen");
                if (webSocketCallback != null) {
                    webSocketCallback.onOpen();
                }
                connected = true;
            }
    
            @Override
            public void onMessage(WebSocket webSocket, String text) {
                Log.d(TAG, "onMessage " + text);
                if (webSocketCallback != null) {
                    webSocketCallback.onMessage(text);
                }
            }
    
            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                Log.d(TAG, "onClosed");
                if (webSocketCallback != null) {
                    webSocketCallback.onClosed();
                }
                connected = false;
                reconnect();
            }
    
            /**
             * Invoked when a web socket has been closed due to an error reading from or writing to the
             * network. Both outgoing and incoming messages may have been lost. No further calls to this
             * listener will be made.
             */
            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                Log.d(TAG, "onFailure " + t.getMessage());
                connected = false;
                reconnect();
            }
        }
    
        /**
         * 只暴露需要的回调给页面,onFailure 你给了页面,页面也无能为力不知怎么处理
         */
        public interface WebSocketCallback {
            void onMessage(String text);
    
            void onOpen();
    
            void onClosed();
        }
    
        public void setWebSocketCallback(WebSocketCallback webSocketCallback) {
            this.webSocketCallback = webSocketCallback;
        }
    }
    

    前端使用时 bind 上Service就行了

    public class MainActivity extends AppCompatActivity {
        WebSocketService webSocketService;
        TextView tvMessage;
        EditText etValue;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            bindService(new Intent(this, WebSocketService.class), serviceConnection, BIND_AUTO_CREATE);
    
            btnClose.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (webSocketService != null) {
                        webSocketService.close();
                    }
                }
            });
            btnSend.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (webSocketService != null) {
                        webSocketService.send(etValue.getText().toString().trim());
                    }
                }
            });
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unbindService(serviceConnection);
        }
    
        private ServiceConnection serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                webSocketService = ((WebSocketService.LocalBinder) service).getService();
                webSocketService.setWebSocketCallback(webSocketCallback);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                webSocketService = null;
            }
        };
    
        private WebSocketService.WebSocketCallback webSocketCallback = new WebSocketService.WebSocketCallback() {
            @Override
            public void onMessage(final String text) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvMessage.setText(text);
                    }
                });
            }
    
            @Override
            public void onOpen() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvMessage.setText("onOpen");
                    }
                });
            }
    
            @Override
            public void onClosed() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvMessage.setText("onClosed");
                    }
                });
            }
        };
    }
    

    demo: https://github.com/lesliebeijing/okhttp-websocket/tree/master

    相关文章

      网友评论

          本文标题:Android OkHttp3 WebSocket

          本文链接:https://www.haomeiwen.com/subject/ebmaihtx.html