okhttp 中的websocket 結合RxJava 的網絡請求封裝。

okhttp 中是自帶websocket 服務的,網上的教程也很是多。可是不少都沒有註明關鍵一步,須要引入 'com.squareup.okhttp3:okhttp-ws:3.4.2' 才能夠調用webscoket 對象,web

先定義一個靜態的全局okhttp對象,方便之後調用json

public static OkHttpClient okHttpClient;
public static WebSocket webSocket = null;
public static MessageCallBack messageCallBack;

public static synchronized void InstancesOkhttp() { if (okHttpClient == null) { okHttpClient = new OkHttpClient().newBuilder(). readTimeout(3000, TimeUnit.SECONDS)//設置讀取超時時間 .writeTimeout(3000, TimeUnit.SECONDS)//設置寫的超時時間 .connectTimeout(3000, TimeUnit.SECONDS)//設置鏈接超時時間 .build(); if (webSocket == null) { initWebsocket(); } } }

接着實例化websocket,websocket

  public static void initWebsocket() {
        String url = "ws://你的地址";
        final Request request = new Request.Builder()
                .url(url).build();
        WebSocketCall webSocketCall = WebSocketCall.create(okHttpClient, request);
        webSocketCall.enqueue(new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                HttpCenter.webSocket = webSocket;

            }

            @Override
            public void onFailure(IOException e, Response response) {
            }

            @Override
            public void onMessage(ResponseBody message) throws IOException {
                String msg = message.string();
                if (messageCallBack == null) {
                    //// TODO: 17/5/20
                }
                else {
                    messageCallBack.onMessage(msg);
                }
            }

            @Override
            public void onPong(Buffer payload) {

            }

            @Override
            public void onClose(int code, String reason) {
                System.out.println("MESSAGE: onClose" + code);
                initWebsocket();
            }
        });
    }

 

很簡單。socket

以後須要統一一個發送方法,同時定義一個用於頁面的回調接口ide

public void setCallBack(MessageCallBack callBack) {
        this.messageCallBack = callBack;
    }

    public void send(String str) {
        final String m = str;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    if (HttpCenter.webSocket != null)
                        HttpCenter.webSocket.sendMessage(RequestBody.create(TEXT, m));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        mExecutor.execute(runnable);
    }

以上基本的封裝結束。佈局

接下來統一消息處理。ui

public class MessageCenter {

    private MessageCallBack MyMessage;
    private WebSocket socket;
    private CommandCenter commandCenter;
    private HttpCenter httpCenter;

    public MessageCenter(MessageCallBack messageCenter) {
        httpCenter = new HttpCenter();

        this.MyMessage = messageCenter;

        httpCenter.setCallBack(messageCenter);

        commandCenter = new CommandCenter();
    }


    public CommandCenter ChooseCommand() {

        if (commandCenter != null)
            return commandCenter;
        else {
            commandCenter = new CommandCenter();
            return commandCenter;
        }
    }

    public void SendYouMessage(String str) {
        Log.i("發送了", str);
        if (HttpCenter.webSocket != null) {
            socket = HttpCenter.webSocket;
        } else {
            HttpCenter.initWebsocket();
        }
        httpCenter.send(str);


    }
    public void setCallBackInterFace(MessageCallBack messageCenter) {
        setHttpCallBack(messageCenter);
    }
    private void setHttpCallBack(MessageCallBack messageCenter) {
        this.MyMessage = messageCenter;
        httpCenter.setCallBack(this.MyMessage);
    }


}

 思路很簡單 ,this

接着根據業務需求定義一個請求類來統一發送接口,url

    private JSONObject jsonObj;
    private JSONObject jsonObjArr;



    /////////////////////////////////////
    private JSONObject addData(JSONObject ob, String name, Object vlaue) {
        try {
            ob.put(name, vlaue);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return ob;

    }

    private JSONObject addCmd(JSONObject cmd, String cmdName, JSONObject data) {

        try {
            cmd.put("cmd", cmdName);
            cmd.put("data", data);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return cmd;
    }

 

封裝部分結束,spa

接下來調用,由於會有大量重複性的代碼,因此先定義一個Activity的基類

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);



        //設置佈局內容
        setContentView(getLayoutId());

        //綁定butterkife
        setButterKnife();

        //初始化控件
        initViews(savedInstanceState);

    }


    public abstract void setButterKnife();

    public abstract int getLayoutId();

    protected abstract void initViews(Bundle savedInstanceState);

    protected void DealMessageForMe(String s, Observer observer){
            Observable.just(s)
                    .observeOn(AndroidSchedulers
                            .mainThread())
                    .subscribe(observer);
    }

}

結合Gson 和Observer來解析和處理數據


observer = new Observer<String>() {
@Override
public void onCompleted() {


}

@Override
public void onError(Throwable e) {

}

@Override
public void onNext(String s) {
JSONObject cmd = JSONUtils.StringToJSON(s);
if (JSONUtils.getString(cmd, "cmd").equals("xxx")) {
swipe.setRefreshing(false);
Gson gson = new Gson();
Type type = new TypeToken<WorkBean>() {
}.getType();
workBean = gson.fromJson(String.valueOf(cmd), type);
listdata.clear();
listdata.addAll(workBean.getData());
adapter.notifyDataSetChanged();
}
}
};

 

PS: 由於接口被聲明爲靜態,因此會出現數據請求混亂的狀況,這是須要在onResume這指定當前的回調接口

messageCenter.setCallBackInterFace(this);
相關文章
相關標籤/搜索