在这里,我们将给大家分享关于如何在Sanic中使用aiohttpClientSession?的知识,同时也会涉及到如何更有效地androidwebview和httpclientsession共享的问题
在这里,我们将给大家分享关于如何在Sanic中使用aiohttp ClientSession?的知识,同时也会涉及到如何更有效地android webview和httpclient session共享的问题、Android 中使用 HttpURLConnection 和 HttpClient 发送 Http 请求、Apache HttpClient临时错误:NoHttpResponseException、AsyncHttpClient保持session的内容。
本文目录一览:- 如何在Sanic中使用aiohttp ClientSession?
- android webview和httpclient session共享的问题
- Android 中使用 HttpURLConnection 和 HttpClient 发送 Http 请求
- Apache HttpClient临时错误:NoHttpResponseException
- AsyncHttpClient保持session
如何在Sanic中使用aiohttp ClientSession?
我试图了解将Sanio与aiohttp一起使用的正确方法是什么。
从aiohttp文档中,我发现以下内容:
不要为每个请求创建会话
。每个应用程序很可能需要一个会话来执行所有请求。更复杂的情况可能需要在每个站点上进行一次会话,例如,一个会话用于Github,另一个会话用于Facebook
API。无论如何,为每个请求建立会话是一个非常糟糕的主意。会话内部包含一个连接池。连接重用和保持活动状态(默认情况下均处于启用状态)可能会提高整体性能。
当我去Sanic文档时,我会找到一个这样的例子:
这是一个例子:
from sanic import Sanicfrom sanic.response import jsonimport asyncioimport aiohttpapp = Sanic(__name__)sem = None@app.route("/")async def test(request): """ Download and serve example JSON """ url = "https://api.github.com/repos/channelcat/sanic" async with aiohttp.ClientSession() as session: async with sem, session.get(url) as response: return await response.json()app.run(host="0.0.0.0", port=8000, workers=2)
这不是管理aiohttp会话的正确方法…
那么正确的方法是什么?
我应该在应用程序中启动会话并将会话注入到所有层中的所有方法吗?
我发现的唯一问题是这个,但这无济于事,因为我需要创建自己的类来使用该会话,而不是sanic。
也可以在Sanic文档中找到此内容,该文档指出您不应在eventloop之外创建会话。
我有点困惑:(正确的方法是什么?
答案1
小编典典为了使用单个aiohttp.ClientSession
实例,我们只需要实例化一次会话,并在应用程序的其余部分中使用该特定实例。
为此,我们可以使用before_server_start
侦听器,该侦听器将允许我们在应用程序提供第一个字节之前创建实例。
from sanic import Sanic from sanic.response import jsonimport aiohttpapp = Sanic(__name__)@app.listener(''before_server_start'')def init(app, loop): app.aiohttp_session = aiohttp.ClientSession(loop=loop)@app.listener(''after_server_stop'')def finish(app, loop): loop.run_until_complete(app.aiohttp_session.close()) loop.close()@app.route("/")async def test(request): """ Download and serve example JSON """ url = "https://api.github.com/repos/channelcat/sanic" async with app.aiohttp_session.get(url) as response: return await response.json()app.run(host="0.0.0.0", port=8000, workers=2)
代码明细:
- 我们正在创建一个
aiohttp.ClientSession
作为参数,将Sanic
应用程序在开始时创建的循环作为参数传递,从而避免了此过程中的陷阱。 - 我们将该会话存储在Sanic中
app
。 - 最后,我们正在使用此会话来发出请求。
android webview和httpclient session共享的问题
@邓凡平 你好,想跟你请教个问题:现在是登录页面嵌套的html5,其他都是原生Android,现在登录成功后,需要保持登录状态,我已经通过cookieManager获取到了html5中的cookie,但是在其他页面进行httpclient请求的时候,还是说我未登录,已经setHeader("Cookie",cookie);
Android 中使用 HttpURLConnection 和 HttpClient 发送 Http 请求
在 android 应用程序中,可以使用 HttpURLConnection 发送 HTTP 请求。详见如下实例
1、activity_main.xml 布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="@+id/send_request"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送请求"
/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</ScrollView>
</LinearLayout>
2、MainActivity.java
package com.example.testhttp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
private Button sendRequest;
private TextView content;
private static final int SHOW_RESPONSE_CONTENT = 0;
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_RESPONSE_CONTENT:
String response = (String) msg.obj;
//显示到界面上
content.setText(response);
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取发送按钮
sendRequest = (Button) findViewById(R.id.send_request);
//获取TextView
content = (TextView) findViewById(R.id.content);
sendRequest.setOnClickListener(this);
}
//重写点击方法
@Override
public void onClick(View view) {
if(view.getId() == R.id.send_request){
//如果是点击发送按钮,则处理Http请求--使用HttpURLConnection
sendRequestWithHttpURLConnection();
}
}
/**
* 使用HttpURLConnection发送请求
*/
public void sendRequestWithHttpURLConnection(){
//新起一线程
new Thread(new Runnable() {
//处理逻辑
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL("http://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
//设置参数
//发送请求
connection.setRequestMethod("GET");
//连接超时时间
connection.setConnectTimeout(5000);
InputStream in = connection.getInputStream();
//对服务器返回的输入流进行读取
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder builder = new StringBuilder();
String line;
while((line = reader.readLine())!=null){
builder.append(line);
}
//使用Message
Message message = new Message();
message.what = SHOW_RESPONSE_CONTENT;
message.obj = builder.toString();
handler.sendMessage(message);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(connection!=null){
//断开连接
connection.disconnect();
}
}
}
}).start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
3、获取网络访问权限
修改 AndroidManifest.xml,添加:
<uses-permission android:name="android.permission.INTERNET"/>
4、结果
点击发送按钮,如下所示:
这就是服务器返回给我吗的 Html 代码。
如果是发送数据给服务器呢?看如下代码:
connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=yy&password=admin");
此外,可以使用 HttpClient 发送 Http 请求,
其他不变,在 MainActivity.java 类中添加方法 sendRequestWithHttpClient,如下:
private void sendRequestWithHttpClient(){
new Thread(new Runnable() {
@Override
public void run() {
try {
HttpClient httpClient= new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://www.baidu.com");
HttpResponse httpResponse = httpClient.execute(httpGet);
if(httpResponse.getStatusLine().getStatusCode() == 200){
//请求和相应成功
HttpEntity entity = httpResponse.getEntity();
//防止中文乱码
String responseText = EntityUtils.toString(entity,"utf-8");
Message message = new Message();
message.what = SHOW_RESPONSE_CONTENT;
message.obj = responseText.toString();
handler.sendMessage(message);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
修改 onClick 方法,如下:
//重写点击方法
@Override
public void onClick(View view) {
if(view.getId() == R.id.send_request){
//如果是点击发送按钮,则处理Http请求--使用HttpURLConnection
// sendRequestWithHttpURLConnection();
//如果是点击发送按钮,则处理Http请求--使用HttpClient
sendRequestWithHttpClient();
}
}
效果如下:
Apache HttpClient临时错误:NoHttpResponseException
我有一个Web服务正在接受XML的POST方法。它工作正常,然后在某个随机的时刻,它无法与服务器通信,并抛出message,并抛出IOExceptionThe target server failed to respond
。后续调用工作正常。
当我打了一些电话然后将应用程序闲置大约10-15分钟时,它就会发生。在此之后我进行的第一个调用将返回此错误。
我尝试了几件事…
我像这样设置重试处理程序
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() { public boolean retryRequest(IOException e, int retryCount, HttpContext httpCtx) { if (retryCount >= 3){ Logger.warn(CALLER, "Maximum tries reached, exception would be thrown to outer block"); return false; } if (e instanceof org.apache.http.NoHttpResponseException){ Logger.warn(CALLER, "No response from server on "+retryCount+" call"); return true; } return false; } }; httpPost.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryHandler);
但是此重试从未被调用过。(是的,我正在使用正确的instanceof子句)。在调试时,此类永远不会被调用。
我什至尝试设置HttpProtocolParams.setUseExpectContinue(httpClient.getParams(),false);
但没有用。有人可以建议我现在可以做什么吗?
重要事项 除了弄清楚为什么我会得到例外,我还有一个重要的担忧是为什么重试处理程序不在这里工作?
答案1
小编典典由连接管理器保持活动状态的最有可能的持久连接变得陈旧。也就是说,目标服务器会在其连接空闲时关闭其末端的连接,而HttpClient无法对该事件做出反应,从而使连接半关闭或“陈旧”。通常这不是问题。HttpClient使用多种技术来验证从池中租借时的连接有效性。即使禁用了过时的连接检查并且使用了过时的连接来传输请求消息,请求执行通常也会在具有SocketException的写操作中失败,并会自动重试。但是,在某些情况下,写操作可以毫无例外地终止,随后的读操作将返回-1(流的结尾)。
解决此问题的最简单方法是将过期的连接和闲置了超过一段时间(例如,在池中闲置一分钟之后)之后空闲的连接驱逐出去。有关详细信息,请参见HttpClient教程的本节。
AsyncHttpClient保持session
需求是用户登录后才可以获取列表
后台通过session判断用户是否登录
android端需要保持session信息
直接代码
AsyncHttpCilentUtil工具类
import android.content.Context;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.PersistentCookieStore;
public class AsyncHttpCilentUtil {
private static AsyncHttpClient client;
public static AsyncHttpClient getInstance(Context paramContext) {
if (client == null) {
client = new AsyncHttpClient();
PersistentCookieStore myCookieStore = new PersistentCookieStore(paramContext);
client.setCookieStore(myCookieStore);
}
return client;
}
}
参考:AsyncHttpClient的CookieStore问题
今天关于如何在Sanic中使用aiohttp ClientSession?的分享就到这里,希望大家有所收获,若想了解更多关于android webview和httpclient session共享的问题、Android 中使用 HttpURLConnection 和 HttpClient 发送 Http 请求、Apache HttpClient临时错误:NoHttpResponseException、AsyncHttpClient保持session等相关知识,可以在本站进行查询。
本文标签: