极光推送C#版本在XP系统下提示“基础连接已经关闭: 接收时发生意外错误”的解决方案
极光推送服务器用的SSL协议版本是TLS1.2,而TLS 1.2 必须要 .NET 4.5或以上版本,然而XP系统是不支持 .NET 4.5或以上版本的。解决方法就是http请求弃用.NET自带的WebRequest,自己使用TCP写HTTPS请求。
两篇参考文章:
.net2.0用TLS1.2+TCP Stream访问https网站
http://blog.csdn.net/atceedsun/article/details/50443657
C# 使用TCPCLIENT模拟HTTP请求的使用
http://www.cnblogs.com/orange-huihui/articles/3266224.html
我的具体做法:
1.cn.jpush.api引用第一篇参考文章里提到的第三方库BouncyCastle.dll;
2.cn.jpush.api的common文件夹下增加一个自定义http请求类,代码如下:
using Org.BouncyCastle.Crypto.Tls;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;namespace cn.jpush.api.common
{// Need class with TlsClient in inheritance chain class MyTlsClient : DefaultTlsClient{public override TlsAuthentication GetAuthentication(){return new MyTlsAuthentication();}}// Need class to handle certificate auth class MyTlsAuthentication : TlsAuthentication{public TlsCredentials GetClientCredentials(CertificateRequest certificateRequest){// return client certificate return null;}public void NotifyServerCertificate(Certificate serverCertificate){// validate server certificate }}public class MyHttp{public static Response HTTP(string _type, string _url, String _auth = "", string _postdata = "", string _cookie = ""){Encoding _responseEncode = Encoding.UTF8;int port = 80;try{if (_url.StartsWith("https", StringComparison.OrdinalIgnoreCase)){port = 443;}else{ }Uri URI = new Uri(_url);TcpClient tcpClient = new TcpClient(URI.Host, port);TlsClientProtocol protocol = new TlsClientProtocol(tcpClient.GetStream(), new Org.BouncyCastle.Security.SecureRandom());MyTlsClient client = new MyTlsClient();protocol.Connect(client);//utf8编码byte[] bs = UTF8Encoding.UTF8.GetBytes(_postdata);StringBuilder RequestHeaders = new StringBuilder();RequestHeaders.Append(_type + " " + URI.PathAndQuery + " HTTP/1.1\r\n");//RequestHeaders.Append("Content-Type: application/x-www-form-urlencoded\r\n");//RequestHeaders.Append("User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11\r\n");//RequestHeaders.Append("Cookie: " + _cookie + "\r\n");//RequestHeaders.Append("Accept: */*\r\n");RequestHeaders.Append("Host: " + URI.Host + "\r\n");RequestHeaders.Append("Content-Length: " + bs.Length + "\r\n");//RequestHeaders.Append("Connection: close\r\n");if (!String.IsNullOrEmpty(_auth)){RequestHeaders.Append("Authorization: " + "Basic " + _auth + "\r\n");}RequestHeaders.Append("\r\n");byte[] request = Encoding.UTF8.GetBytes(RequestHeaders.ToString() + _postdata);//发送http请求 protocol.Stream.Write(request, 0, request.Length);protocol.Stream.Flush();//读取返回内容 MemoryStream ms = new MemoryStream();byte[] buffer = new byte[1024000];int actual = 0;//先保存到内存流MemoryStream中try{if ((actual = protocol.Stream.Read(buffer, 0, 1024000)) > 0){ms.Write(buffer, 0, actual);}}catch { }ms.Position = 0;byte[] bImageBytes = ms.ToArray();string result = Encoding.UTF8.GetString(bImageBytes);//Console.WriteLine(result);int headerIndex = result.IndexOf("\r\n\r\n");string[] headerStr = result.Substring(0, headerIndex).Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);Dictionary<string, string> responseHeader = new Dictionary<string, string>();for (int i = 0; i < headerStr.Length; i++){string[] temp = headerStr[i].Split(new string[] { ": " }, StringSplitOptions.RemoveEmptyEntries);if (temp.Length == 2){if (responseHeader.ContainsKey(temp[0])){responseHeader[temp[0]] = temp[1];}else{responseHeader.Add(temp[0], temp[1]);}}}Response response = new Response();response.HTTPResponseHeader = responseHeader;string[] httpstatus = headerStr[0].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);if (httpstatus.Length > 2){response.HTTPStatusCode = httpstatus[1];}else{response.HTTPStatusCode = "400";}response.HTTPResponseText = _responseEncode.GetString(Encoding.UTF8.GetBytes(result.Substring(headerIndex + 4)));return response;}catch{return null;}}}public class Response{string hTTPStatusCode;/// /// http状态代码 /// public string HTTPStatusCode{get { return hTTPStatusCode; }set { hTTPStatusCode = value; }}Dictionary<string, string> hTTPResponseHeader;/// /// Response的header /// public Dictionary<string, string> HTTPResponseHeader{get { return hTTPResponseHeader; }set { hTTPResponseHeader = value; }}string hTTPResponseText;/// /// html代码 /// public string HTTPResponseText{get { return hTTPResponseText; }set { hTTPResponseText = value; }}}
}
3.将cn.jpush.api的common文件夹下的BaseHttpClient.cs里的
public ResponseWrapper sendRequest1(String method, String url, String auth,String reqParams)
方法替换为:
public ResponseWrapper sendRequest(String method, String url, String auth, String reqParams){//结果wrapResponseWrapper result = new ResponseWrapper();try{//response//调用自定义http请求,因为极光推送服务器使用的SSL-TLS1.2版本,必须要.net4.5以上框架才支持,所以只能使用自定义http请求并调用第三方ssl框架实现Response response = MyHttp.HTTP(method, url, auth, reqParams);//http status codeHttpStatusCode statusCode = (HttpStatusCode)Convert.ToInt32(response.HTTPStatusCode);result.responseCode = statusCode;if (Equals(statusCode, HttpStatusCode.OK)){Regex regpatton = new Regex(@"{(.*)}");MatchCollection jsons = regpatton.Matches(response.HTTPResponseText);if (jsons.Count > 0){result.responseContent = jsons[0].ToString(); }String limitQuota = response.HTTPResponseHeader[RATE_LIMIT_QUOTA];String limitRemaining = response.HTTPResponseHeader[RATE_LIMIT_Remaining];String limitReset = response.HTTPResponseHeader[RATE_LIMIT_Reset];result.setRateLimit(limitQuota, limitRemaining, limitReset);Console.WriteLine("Succeed to get response - 200 OK" + " " + DateTime.Now);Console.WriteLine("Response Content - {0}", result.responseContent + " " + DateTime.Now);}}catch { }return result;}
4.提示有引用问题的,使用修复功能增加相应的引用就成了。
至此,大功告成!
PS:写的比较清楚了,就没有上传完整示例,实在有需要可以向402143909@qq.com索取。
极光推送C#版本在XP系统下提示“基础连接已经关闭: 接收时发生意外错误”的解决方案相关推荐
- 苹果推送证书在钥匙串的系统下的解决方案
我们都知道,在开发者账号里边创建苹果推送证书的时候,需要把cer证书导出成p12以供第三方后台使用,比如 极光推送.友盟推送.百度推送.个推推送等后台.以往都没有出现过什么问题,今天推送cer证书创建 ...
- 基于极光推送的web,app消息系统
设计要点 1.web,app注册系统同时注册极光IM 2.WEB集成IM sdk,用户WEB登录与极光IM建立长连接 3.后端调用极光IM API给WEB用户推送消息,并将信息存入持久化到DB 4.用 ...
- 解决在极光推送的时候会出现一个 JPush提示:缺少统计代码
<span style="font-size:14px;">@Override protected void onResume(){super.onResume();J ...
- 用JPUSH极光推送实现服务端向安装了APP应用的手机推送消息(C#服务端接口)
这次公司要我们做一个功能,就是当用户成功注册以后,他登录以后要收到消息,当然这个消息是安装了我们的手机APP应用的手机咯. 极光推送的网站的网址是:https://www.jpush.cn/ 极光推送 ...
- Android集成极光推送踩坑(二)升级篇
转载请标明出处 http://blog.csdn.net/mohan6/article/details/74133186 本文作者:[默寒的博客] 前言 前段时间针对集成极光推送写了篇文章( Andr ...
- 看了极光推送技术原理的几点思考
看了极光推送技术原理的几点思考 分类: android2012-11-26 20:50 16586人阅读 评论(18) 收藏 举报 目录(?)[+] 移动互联网应用现状 因为手机平台本身.电量.网络流 ...
- 使用极光推送发送短信验证码
发送短信验证码 1.获取AppKey和Master Secret 2.设置短信模板和短信签名 3.开始服务端接口的实现 1.获取AppKey和Master Secret 首先应有一个极光推送官网的账号 ...
- Android 极光推送 自定义通知铃声
公司使用的推送功能使用的是极光推送,对于普通的通知,极光推送API自动集成了声音的提示,但是对于一些特殊的情况,我们就需要自定义声音提示. 有点坑的是极光并没有提供设置自定通知铃声的接口,所以只能自己 ...
- 从极光推送的实现原理概括iOS和Andriod推送原理
推送是手机中非常常见的功能了.可是在实现上iOS和Andriod却有很大的差别. 因为iOS有强大的产品生态体系,APP从研发到审核上架,再到最后在手机端运行,都有严格的把关.所以推送功能在它这里实现 ...
最新文章
- 安装 SQL Server 商业解决方案模板
- iOS安全之二次封装AFN并设置请求头/执行HTTPS加强安全
- 【番外篇3】xdd-plus 登录时发生致命错误以及小滴滴拉取代失败的解决办法
- 各厂商防火墙初始登录IP及密码信息
- new、delete、malloc、free 在堆栈上的使用区别 C++
- Ant Design 3.0 使用案例
- Kruskal+LCA【p2245】 星际导航
- MySql优化 (2009-08-28 系统架构师大会) 演讲ppt
- ffmepg 命令提取音视频数据
- linux标准I/O——按字符输入和输出
- azure db 设置时区_使用Azure Cosmos DB开始您的旅程
- 【jQuery】jQuery操作input的聚焦与全选其内容
- docker如何配置阿里云加速器
- 天池性能挑战赛-高性能分析型查询引擎复赛12名赛后方案分享
- Android-APP之桌面宠物
- 停车位配建标准:北上广深
- 怎样用计算机才能更快,如何让网速变快,详细教您怎么让电脑网速变快
- 如何解救爆红的C盘?
- 解读中国版新资本协议
- 闲谈mac地址学习以及IVL/SVL