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);