Java实现客户端与服务器端的通信

客户端与服务器端交互数据需要进行通信,本文介绍安卓客户端是如何与服务器端进行通信的,包括客户端连接服务器端、客户端向服务器端发送请求、将请求信息封装成请求单元、将请求单元存放到队列、从队列中获取请求单元并执行请求。主要的步骤为:”客户端配置请求服务器的ip地址”、“”客户端向服务器端发送请求”、“将一个请求封装成请求单元HttpRequestUnit”、“将请求单元放到一个队列中,开启一个线程执行队列中的请求”、“HttpRequestManager类负责缓存和获取HttpRequestThread对象”。

1、客户端配置请求服务器的ip地址。

设置服务器的IP地址,如果是在自己的电脑运行服务器项目,那就设置成电脑的ip地址,然后客户端和电脑要连接同一个网络,确保在同一局域网。

(1)打开cmd命令行窗口,输入ipconfig命令查看电脑的本机ip地址。

CMD命令ipconfig查IP

(2)在Configuration类配置服务器ip地址。

public final class Configuration {
    public static final String APP_Config_Key_env = "env";

    public static final String SERVER_IP_DEV = "https://dev.wx.bxit.vip/";
    public static final String SERVER_IP_SIT = "https://sit.wx.bxit.vip/";
    public static final String SERVER_IP_UAT = "https://uat.wx.bxit.vip/";
    public static final String SERVER_IP_PRODUCTION = "https://account.prosalesbox.cn/";

    public static String HTTP_IP = "http://192.168.123.144/";//运行Pos_Local测试时,要确保与Pos在同一局域网;搞清楚NBR的IP是多少,并填写在这里

2、客户端向服务器端发送请求。

(1)创建请求体RequestBody对象。

RequestBody body = new FormBody.Builder()
        .add(staff.field.getFIELD_NAME_phone(), staff.getPhone())
        .build();

(2)创建Request对象。

Request request = new Request.Builder()
        .url(Configuration.HTTP_IP + "staff/getTokenEx.bx")
        .addHeader(BaseHttpBO.COOKIE, GlobalController.getInstance().getSessionID())
        .post(body)
        .build();

(3)发送请求。

httpEvent.setStatus(BaseEvent.EnumEventStatus.EES_Http_ToDo);
HttpRequestUnit hru1 = new StaffGetToken();
hru1.setRequest(request);
hru1.setTimeout(TIME_OUT);
hru1.setbPostEventToUI(true);
hru1.setEvent(httpEvent);
HttpRequestManager.getCache(HttpRequestManager.EnumDomainType.EDT_Communication).pushHttpRequest(hru1);

3、将一个请求封装成请求单元HttpRequestUnit。

HttpRequestUnit定义为一个请求单元,它实现了okhttp3.Call接口,实现了请求成功和请求失败的回调方法onResponse和onFailure:

public abstract class HttpRequestUnit implements Callback

(1)     请求成功后执行onResponse方法。

获取到服务器返回的数据,做下一步处理:

@Override
public void onResponse(Call call, Response response) throws IOException {
    log.info("请求后返回的response:" + response);
    dateEnd = new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference);
    if (isTimeout(call)) {
        event.setLastErrorCode(ErrorInfo.EnumErrorCode.EC_Timeout);
        return;
    }
    log.info(" Http onResponse,收到服务器的响应");
    if (NtpHttpBO.bForNtpOnly) {// 在同步的时候设置POS接收到答复的时间,用于POS机与服务器同步时间
        event.setData(new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference).getTime());
        NtpHttpBO.bForNtpOnly = false;
    }
    event.setLastErrorCode(ErrorInfo.EnumErrorCode.EC_NoError);
    if (bPostEventToUI) {
        event.setRequestType(getEnumRequestType());
        event.setResponseData(response.body().string());
        event.setResponse(response);
        //...设置Event状态???
        EventBus.getDefault().post(event);
    }
}

(2)请求失败后执行onFailure方法。

@Override
public void onFailure(Call call, IOException e) {
    this.event.setEventProcessed(true); //终止UI层的等待
    //...
    log.info(" Http onFailure,向服务器发送请求失败。异常信息:" + e.getMessage());
    dateEnd = new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference); //用于计算超时
    if (isTimeout(call)) {
        event.setLastErrorCode(ErrorInfo.EnumErrorCode.EC_Timeout);
    } else {
        event.setLastErrorCode(ErrorInfo.EnumErrorCode.EC_OtherError);
    }
    this.event.setLastErrorMessage(BaseHttpBO.ERROR_MSG_Network);
    //
    GlobalController.getInstance().setSessionID(null);
    //
    EventBus.getDefault().post(event);
}

4、将请求单元放到一个队列中,开启一个线程执行队列中的请求。

HttpRequestThread 继承了 Thread,负责将一个个HttpRequestUnit放到队列当中,并且开启一个线程,不停的从队列中获取HttpRequestUnit,执行请求:

public class HttpRequestThread extends Thread {

protected Queue<HttpRequestUnit> queue;

(1)将请求单元HttpRequestUnit放到队列queue中。

public void pushHttpRequest(HttpRequestUnit hu) {
    if (hu != null) {
        lock.writeLock().lock();
        queue.offer(hu);
        lock.writeLock().unlock();
    }
    synchronized (this) {
        notify();
    }
}

(2)启动线程的run方法,执行doTask()方法。

@Override
public void run() {
    while (atomicInteger.get() != SIGNAL_ThreadExit) {
        lock.writeLock().lock();
        doTask();
        lock.writeLock().unlock();
        synchronized (this) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    log.info("线程:" + this.getName() + "已经退出");
}

(3)doTask方法从队列中获取请求单元HttpRequestUnit,并交给okhttp3.OkHttpClient对象执行请求。

protected void doTask() {
    while (!queue.isEmpty()) {
        lock.writeLock().lock();
        HttpRequestUnit hu = queue.poll();
        if (hu == null) {
            lock.writeLock().unlock();
            break;
        }
        hu.setDateStart(new Date(System.currentTimeMillis() + NtpHttpBO.TimeDifference));
        GlobalController.client.newCall(hu.getRequest()).enqueue(hu);
        lock.writeLock().unlock();
    }
}

(4)client为okhttp3.OkHttpClient对象。

//设置OKHttp的超时时间
public static OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(HTTP_REQ_Timeout, TimeUnit.SECONDS)
        .readTimeout(HTTP_REQ_Timeout, TimeUnit.SECONDS)
        .writeTimeout(HTTP_REQ_Timeout, TimeUnit.SECONDS)
        .build();
5、HttpRequestManager类负责缓存和获取HttpRequestThread对象。
public class HttpRequestManager {
    public enum EnumDomainType {
        EDT_Communication("EDT_Communication", 0), //
        EDT_Authentication("EDT_Authentication", 1);
	……

private static HashMap<EnumDomainType, HttpRequestThread> list = new HashMap<EnumDomainType, HttpRequestThread>();

public static void register(EnumDomainType ect, HttpRequestThread bc) {
    list.put(ect, bc);
}

public static HttpRequestThread getCache(EnumDomainType ect) {
    return list.get(ect);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值