HttpClient session

session概述

session机制

session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。

当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。 保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发回给服务器。一般这个cookie的名字都是类似于SEEESIONID,而。比如weblogic对于web应用程序生成的cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID。

session,简而言之就是在服务器上保存用户操作的历史信息。服务器使用session id来标识session,session id由服务器负责产生,保证随机性与唯一性,相当于一个随机密钥,避免在握手或传输中暴露用户真实密码。但该方式下,仍然需要将发送请求的客户端与session进行对应,所以可以借助cookie机制来获取客户端的标识(即session id),也可以通过GET方式将id提交给服务器。

  • session的原理图:

HttpClient session的使用

下面我们结合实例来学习session的一个简单使用场景。玩家登陆游戏,登陆成功,服务器返回sessionID标识此次会话。后面的领取每日登陆奖励请求中都加入此sessionID,服务器上保存用户操作的历史信息实现服务端管理客户端的功能。根据sessionID管理登陆的玩家的会话,并更新玩家领取奖励信息。

服务器接口设计

根据上面设计的使用场景,我们的服务器需要支持玩家登录和更新每日登录领取奖励。我们设计了如下的两个服务器接口:

登陆接口

  • URL

    http://host:port/devicelogin

  • Method

    POST

  • 参数

    1

    2

    3

    {

    "DeviceID" : "device id of the phone"

    }

  • 返回值

    http response code 200,登陆成功,http头部set-cookie自动包含sessionID。


    1

    2

    3

    4

    {

    "IsLottery" : true,

    "NoLootCount" : 0

    }

参数1:今日是否已领取每日奖励 参数2:装备宝箱未出高级装备次数

客户端解析sessionID,并放入后续http请求中。

更新每日奖励接口

  • URL

    http://host:port/lotteryed

  • Method

    POST

  • 参数

    NULL

  • 返回值

    http response code 200(更新成功)

客户端实现

工程创建

打开终端,使用如下命令新建工程:


1

cocos new HelloWorld -p com.your_company.HelloWorld -l cpp

按照上面的操作,我们新建了一个Cocos2d-x v3.x的HelloWorld工程。

工程创建好后,让我们来完成httpClient的post请求玩家登陆,和每日登陆领取金币奖励的客户端网络处理。 在上一节如何使用httpClient中已经介绍了httpClient的用法。 下面我们直接进入正题,开始编写代码

首先,在HelloWorldScene.cpp文件中加入下面的实现。 引入头文件和命名空间


1

2

#include "network/HttpClient.h"

using namespace cocos2d::network;

login

登陆请求实现

根据服务器接口,新建http请求,添加请求参数。实现代码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

void HelloWorld::login()

{

    HttpRequest* request = new HttpRequest();

    request->setUrl("http://172.100.104.128:8001/devicelogin");//1

    request->setRequestType(HttpRequest::Type::POST);

    request->setResponseCallback(CC_CALLBACK_2(HelloWorld::onLoginHttpRequestCompleted,this));

    // 添加post请求参数

    const char* postData = "{\

    \"DeviceID\" : \"device id of the phone\"\

    }";

    request->setRequestData(postData, strlen(postData));//2

    request->setTag("login POST");//3

    //cocos2d::network::HttpClient::getInstance()->enableCookies(NULL);

    cocos2d::network::HttpClient::getInstance()->send(request);

    request->release();

}

  1. 设置登陆请求url
  2. 添加请求参数
  3. 设置http请求的tag

登陆的请求回调处理

上面的登陆请求设置了onLoginHttpRequestCompleted方法作为响应函数。无论服务器返回怎样的状态onLoginHttpRequestCompleted都将被调用。在响应方法中我们加入了打印登陆返回信息的代码。实现如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

void HelloWorld::onLoginHttpRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response)

{

    if (!response)

    {

        return;

    }

    if (0 != strlen(response->getHttpRequest()->getTag()))

    {

        log("%s completed", response->getHttpRequest()->getTag());

    }

    //打印 http header信息

    std::vector<char> *header = response->getResponseHeader();

    for (unsigned int i = 0; i < header->size(); i++)

    {

        printf("%c", (*header)[i]);

    }

    printf("\n");

    //TODO 登陆成功,服务器会通过set-Cookie,返回sessionID,解析sessionID并保存,用于接下来的请求

    int statusCode = response->getResponseCode();

    log("response code: %d", statusCode);

    if (!response->isSucceed())

    {

        log("response failed");

        log("error buffer: %s", response->getErrorBuffer());

        return;

    }

    // 打印 response data

    std::vector<char> *buffer = response->getResponseData();

    for (unsigned int i = 0; i < buffer->size(); i++)

    {

        printf("%c", (*buffer)[i]);

    }

    printf("\n");

}

编译并运行程序。查看登陆请求的的打印信息。

登陆成功的打印信息如下:


1

2

3

4

5

6

7

8

HTTP/1.1 200 OK

Set-Cookie: GSessionID=MTQwNjI1Mjg3MnxEdi1CQkFFQ180SUFBUkFCRUFBQV8tWF9nZ0FIQm5OMGNtbHVad3dGQUFOMVNVUUdkV2x1ZERNeUJnSUFCUVp6ZEhKcGJtY01DZ0FJWkdWMmFXTmxTVVFHYzNSeWFXNW5EQmdBRm1SbGRtbGpaU0JwWkNCdlppQjBhR1VnY0dodmJtVUdjM1J5YVc1bkRBb0FDRzVwWTJ0T1lXMWxCbk4wY21sdVp3d0NBQUFHYzNSeWFXNW5EQWtBQjJGalkyOTFiblFHYzNSeWFXNW5EQUlBQUFaemRISnBibWNNQ3dBSmFYTk1iM1IwWlhKNUJHSnZiMndDQWdBQUJuTjBjbWx1Wnd3TkFBdHViMHh2YjNSRGIzVnVkQU5wYm5RRUFnQUFCbk4wY21sdVp3d0tBQWgxYzJWeVJHRjBZUVp6ZEhKcGJtY01BZ0FBfGH2499HK_RENNLNURPmZcbqXAhNonoWkv926tH3MJwC; Path=/; Expires=Fri, 25 Jul 2014 02:47:52 UTC; Max-Age=3600; HttpOnly

Date: Fri, 25 Jul 2014 01:47:52 GMT

Content-Length: 35

Content-Type: text/plain; charset=utf-8

cocos2d: response code: 200

Http Test, dump data: {"IsLottery":false,"NoLootCount":0}

通过打印信息,我们可以看到登陆请求,服务器返回的信息中,通过Set-Cookie返回了SessionID。

lotteryed

每日登陆奖励

将登陆成功返回的SessionID,加入到http请求的header中进行每日登陆奖励请求。 每日登陆奖励的网络请求的代码和登陆的请求代码很相似,区别在于他们拥有各自的url、网络请求完成的响应处理和不同的请求tag。

实现要点:

在http header中加入SessionID的Cookie,发起请求。

实现代码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

void HelloWorld::lottery()

{

    HttpRequest* request = new HttpRequest();

    request->setUrl("http://172.100.104.128:8001/lotteryed");//1

    request->setRequestType(HttpRequest::Type::POST);

    request->setResponseCallback(CC_CALLBACK_2(HelloWorld::onHttpRequestCompleted,this));

    //setHeader

    std::vector<std::string> headers;

    headers.push_back("Cookie: GSessionID=MTQwNjI1NjIxMXxEdi1CQkFFQ180SUFBUkFCRUFBQWNfLUNBQU1HYzNSeWFXNW5EQW9BQ0dSbGRtbGpaVWxFQm5OMGNtbHVad3dZQUJaa1pYWnBZMlVnYVdRZ2IyWWdkR2hsSUhCb2IyNWxCbk4wY21sdVp3d0xBQWxwYzB4dmRIUmxjbmtFWW05dmJBSUNBQUVHYzNSeWFXNW5EQTBBQzI1dlRHOXZkRU52ZFc1MEEybHVkQVFDQUFBPXz_BEw8Oo-XGEbCambVDQt2o636QUT_qg2Aj1EZX97ekw==");

    request->setHeaders(headers);//2

    //cocos2d::network::HttpClient::getInstance()->enableCookies(NULL);

    request->setTag("lotteryed POST");//3

    cocos2d::network::HttpClient::getInstance()->send(request);

    request->release();

}

  1. 设置每日登陆奖励的请求url
  2. 将sessionID加入到http请求的头部
  3. 设置http请求的tag

领取每日登陆奖励的网络请求回调处理

在http请求完成的回调中,我们可以通过请求tag区分,当前回调对应哪个网络请求。当然也可以使用setResponseCallback方法设置对应的响应回调处理方法。

由于lottery的http请求回调没返回什么实际参数。奖励领取成功返回http response code 200。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

void HelloWorld::onLotteryHttpRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response)

{

    if (!response)

    {

        return;

    }

    int statusCode = response->getResponseCode();

    log("response code: %d", statusCode);

    if (!response->isSucceed())

    {

        log("response failed");

        log("error buffer: %s", response->getErrorBuffer());

        return;

    }

    //TODO领取奖励成功

}

编译并运行,输出如下信息:


1

cocos2d: response code: 200

response code: 200 表明使用sessionID进行的每日登陆奖励领取的网络请求成功了。

sessionID的其他实现方式:

在3.x的版本中,HttpClient::enableCookies方法支持http会话使用cookie。 由于sessionID的保存和传递是通过cookie实现的,所以我们可以很方便的使用HttpClient::enableCookies方法来实现http client session。


1

cocos2d::network::HttpClient::getInstance()->enableCookies(NULL);

小结

通过以上的玩家登陆游戏和领取每日登陆的网络请求,我们学习了httpclient session的使用。

时间: 2024-10-10 07:41:09

HttpClient session的相关文章

Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点和性能对比

比较的指标: 1.cpu 2.流量 3.电量 4.内存占用 5.联网时间 功能点: 1.重试机制 2.提供的扩展功能 3.易用性 4.是否https 5.是否支持reflect api,OkHttp有配套方法 6.缓存.重试 7.cookie支持session  id会话支持 8.弱网性能和稳定性 9.超时时间,几种超时时间   连接超时,响应超时 10.适配各种机型.4.4和之前版本  2.3  4.1 5.0 4种网络连接方式提供的功能对比表格: 缓存 重试 Https/Http 稳定性 C

大叔也说Xamarin~Android篇~为HttpClient共享Session,android与api的session共享机制

杂谈 在进行android进行开发时,我们的数据一般通过接口来获收,这里指的接口泛指web api,webservice,wcf,web应用程序等:它们做为服务端与数据库进行直接通讯,而APP这块通过向这些接口发Http请求来获得数据,这样的好处大叔认为,可以有效的降低软件的开发难度,所以数据交互都被分离到了服务层而,而与客户交互的功能完全都在APP端,这类似于目前比较流行的SOA架构,即一个服务为多种终端服务:无论是你WEB网站,手机IOS,手机Android,平板还是其它TV之类的,都统一调

webview HttpClient 怎么保持会话session统一

cookies session均为key---value的形式展示,  1.    session是存储在服务端,并有一块区域控件存储用户信息,主要是为了判断该用户是否登录,在客户端采用httpClient/HttpUrlConnection进行登录请求的时候,传过去的username=“ccc” 服务端中的session进行判断是否存在改sessionId,以及value,不存在代表改用户不曾登录,服务器会自动生成唯一的sessionId其为key,传过来的ccc则为value,key="se

Android 通过httpclient请求web服务器,并解决用户登录session保持

package com.rainet.tiis.network; import java.util.Iterator;import java.util.List;import java.util.Map; import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.CookieStore;import org.apache.http.client.Ht

httpClient 保持session

import org.apache.commons.httpclient.Cookie;  import org.apache.commons.httpclient.HttpClient;  import org.apache.commons.httpclient.cookie.CookiePolicy;  import org.apache.commons.httpclient.NameValuePair;  import org.apache.commons.httpclient.metho

HttpClient使用详解 (一)

Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性.因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入. 一.简介 HttpClient是Apache Jakarta Common下的子项目,用

HttpClient的CircularRedirectException异常原因及解决办法

HttpClient的CircularRedirectException异常原因及解决办法 这两天在使用我自己爬虫抓取网页的时候总是出现 org.apache.http.client.ClientProtocolException at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909) at org.apache.http.impl.client.AbstractHttpClie

Atitit.http httpclient实践java c# .net php attilax总结

1. Navtree>> net .http1 2. Httpclient理论1 2.1. 自动url转向的控制1 3. Java里面的httpclient1 4. C# .net的httpclient2 4.1.1. .NET 4.5(C#):2 4.2. 对COOKIE和SEIION支持区别3 4.3. 用户对是否自动url转向的控制3 4.4. 对用户代理服务器的支持3 5. Php的httpclient3 6. Node.js4 7. solu解决问题::4 8. ref参考资料4 8

HttpClient和HttpURLConnection整合汇总对比

性能 1.HttpUrlConnection直接支持GZIP压缩:HttpClient也支持,但要自己写代码处理. 2.HttpUrlConnection直接支持系统级连接池,即打开的连接不会直接关闭,在一段时间内所有程序可共用:HttpClient当然也能做到,但毕竟不如官方直接系统底层支持好. 3.HttpUrlConnection直接在系统层面做了缓存策略处理(4.0版本以上),加快了重复请求的速度. 4.关于速度方面,网上有些大牛做过测试,但因访问站点的数据量,二次连接访问等发现测试结果