Rxjava 封装Socket 网络请求

1项目中接口需要使用socket网络请求,大概有十几个接口。之前用过rxjava简单封装过些简单的http请求的接口,
现在也想按照那种思维模式老封装一下。总体思路是发送数据时传一个bean过去,接收时直接返回已经解析好的
bean,用面向对象的方法编程。如果像以前一样一个工具类中写死好多socket请求的方法,这样耦合性太强,牵一发动全身。 所以使用rxjava 2.0小小封装一下。


2:核心工具类简介

package com.socketutil;

import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Arrays;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by admin on 2018/8/3.
 */

public class RxSocket {
    static RxSocket rxSocket;
    OutputStream outputStream = null;
    Socket socket = null;
    InputStream inputStream = null;
    /** 读取数据超时时间 */
    final int READ_TIMEOUT = 15 * 1000;
    /** 连接超时时间 */
    final int CONNECT_TIMEOUT = 5 * 1000;
    final String IP = "218.29.74.138";
    final int PORT = 11274;
    final String TAG = "RxSocket-->",SUCCEED="初始化成功",TIMEOUT="连接超时",SEND_ERROR="发送数据异常";
    /** 网络返回的监听 */
    SocketListener observer;
    public boolean isCancle = false;

    private RxSocket() {
        Observable.just("")
                .subscribeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .doOnNext(s -> initSocket(IP, PORT))
                .subscribe(s -> Log.d(TAG, SUCCEED));
    }

    public static RxSocket getInstance() {
        if (rxSocket == null) {
            rxSocket = new RxSocket();
        }
        return rxSocket;
    }


    /**
     * 初始化蓝牙通信,需要放在子线程
     * @param ip {@link RxSocket#IP}  ip地址
     * @param port {@link RxSocket#PORT} 端口号
     */
    private void initSocket(String ip,int port) throws Exception{
        try {
            socket = new Socket();
            socket.setSoTimeout(READ_TIMEOUT);
            Log.d(TAG, ip+":"+port);
            socket.connect(new InetSocketAddress(InetAddress.getByName(ip),port),CONNECT_TIMEOUT);
            outputStream = socket.getOutputStream();
            inputStream = socket.getInputStream();
        } catch (IOException e) {
            Log.d(TAG, TIMEOUT);
            e.printStackTrace();
            throw new Exception(TIMEOUT);
        }
    }

    /**
     * 发送数据
     * @return 接口返回的数据
     */
    private String sendData(String data) throws Exception{
        StringBuilder result = new StringBuilder("");
        try {
            outputStream.write(data.getBytes("UTF-8"));
            byte[] b = new byte[1024];
            int reads = inputStream.read(b);
            while (reads > 0) {
                byte[] bytes = Arrays.copyOfRange(b, 8, reads);
                String temp = new String(bytes);
                result.append(temp);
                reads = 0;
                b = new byte[1024];
                reads = inputStream.read(b);
            }
            Log.d(TAG, result.toString());
            return result.toString();
        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
            e.printStackTrace();
            throw new Exception(SEND_ERROR);
        }
    }

    /**
     * 取消所有的请求
     * @param isCancle true:取消访问  false:允许访问
     */
    public void cancleAll(boolean isCancle) {
        this.isCancle = isCancle;
        observer.cancleListen();
    }

    /**
     * socket 发送数据,并返回数据
     * @param baseRequestBean  可以一次发送多个请求
     *                         (后期可以添加重试机制)
     */
    public void request(BaseRequestBean ...baseRequestBean) {
        if (observer!=null)
        Observable.fromArray(baseRequestBean)
                .subscribeOn(Schedulers.io())
                .filter(baseRequestBean1 -> isCancle)
                .map(baseRequestBean1 -> {
                    String result = sendData(baseRequestBean1.get());
                    if (result.length()>0 && isCancle)
                        baseRequestBean1.parseData(result);
                    return baseRequestBean1;
                })
                .filter(baseRequestBean1 -> isCancle)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    /**
     * 设置网络返回的监听
     * @param listener
     */
    public void setResultListener(SocketListener listener) {
        this.observer = listener;
    }
}

 

3:使用方法

//注册请求的回调
RxSocket.getInstance().setResultListener(new SocketListener(){
 @Override
 public void onSuccess(BaseRequestBean bean){
	if(bean.method.eqals(login.method)){

	}else if(bean.method.eqals(login3.method)){

	}
 }
 @Override
  public void onExecption(Throwable throwable){
 }
})

//定义解析的bean
class LoginRes {

  String name;
}

//定义请求的bean,可以写成一个类 把泛型写上
class Login extends BaseRequestBean{
	public Login(){
	  super();
	}

    @Override
    String getRequsetData() {
        return "BBFFAAA";
    }

    @Override
    LoginRes parseData(String data) {
        //解析规则,并返回对应的bean
	return new LoginRes();
    }

    @Override
    String methods() {
	return "login";
    }
}

//只有1个网络请求
Login login = new Login();
RxSocket.getInstance().request(login);

//多个网络请求
RxSocket.getInstance().request(login,login1,login2,login3);

4:问题

对于异常处理全部内部捕捉了,这个不是一个好策略,应该直接抛处理给rxjava,并应该在onError方法中
根据不同逻辑不同处理。如果大家需要使用的话还是建议先按照自己的需求改造下,再使用,有可能有bug

 

其他的类也一起放上来

/**
 * Created by admin on 2018/8/3.
 */
public interface SupplierHeader  {
        /**
         * Gets a result.
         * @return a result
         */
        T getHeader();
}





/**
 * Created by admin on 2018/8/3.
 */
public interface Supplier  {
        /**
         * Gets a result.
         * @return a result
         */
        T get();
}




/**
 * Created by admin on 2018/8/3.
 */

public abstract class SocketListener implements Observer {

    abstract void onSuccess(BaseRequestBean bean);
    abstract void onExecption(Throwable throwable);

    Disposable disposable;
    @Override
    public void onSubscribe(Disposable disposable) {
        this.disposable = disposable;
    }

    @Override
    public void onNext(BaseRequestBean bean) {
        onSuccess(bean);
    }

    @Override
    public void onError(Throwable throwable) {
        onExecption(throwable);
    }

    @Override
    public void onComplete() {

    }

    /**
     * 取消socket 监听
     */
    public void cancleListen() {
        if (disposable!=null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }
}





/**
 * Created by admin on 2018/8/3.
 * Socket 请求和返回的鸡肋
 * 1:请求时组织请求的数据
 * 2:解析时根据返回的数据相应解析
 */

public abstract class BaseRequestBean implements Supplier,Consumer,SupplierHeader {

    abstract String getRequsetData();

    abstract T parseData(String data);

    public T resultBean; //解析结果的bean

    public String method;//标记请求

    String methods();//标记请求
	
   public BaseRequestBean (){
	method=methods();
    }

    /**
     * socket 发送数据的回掉接口
     * @return 需要发送的数据
     */
    @Override
    public String get() {
        return getRequsetData();
    }

    /**
     * 接收socket 返回的数据回掉;
     * @param s
     * @throws Exception
     */
    @Override
    public void accept(String s) throws Exception {
        parseData(s);
    }

    /**
     * Socket请求头接口
     * @return socket报文头
     */
    @Override
    public String getHeader() {
        return null;
    }
}




 

 

 

你可能感兴趣的:(Android开发,Rxjava)