赞
踩
Unity商店有一款评分很高的网络通信插件BestHttp。笔者做了一些简单测试。官方地址:https://assetstore.unity.com/packages/tools/network/best-http-2-155981
Demo工程及插件,会在文章末尾提供。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using BestHTTP;
- using BestHTTP.Authentication;
- using BestHTTP.Cookies;
- using System;
- using System.Text;
- using System.IO;
- using Org.BouncyCastle.Crypto.Tls;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
- using BestHTTP.Statistics;
- using BestHTTP.WebSocket;
- using BestHTTP.WebSocket.Frames;
- using BestHTTP.SocketIO;
- using BestHTTP.SignalR;
- /*
- * Author:W
- * Http协议处理
- */
-
- /// <summary>
- /// 实现服务器证书验证接口
- /// </summary>
- public class CustomVerifier : ICertificateVerifyer
- {
- public bool IsValid(Uri serverUri, X509CertificateStructure[] certs)
- {
-
- // TODO: Return false, if validation fails
- return true;
- }
- }
-
- public delegate void OnServerCallBack(Socket socket, Packet originalPacket, params object[] args);
-
- public class HttpTest : MonoBehaviour {
-
- private HTTPRequest request1;
-
- /// <summary>
- /// 大文件流式请求,下载的文件存放到某一个文件目录下
- /// </summary>
- private HTTPRequest streamReq;
-
- /// <summary>
- /// 大文件上传请求
- /// </summary>
- private HTTPRequest upStreamReq;
-
-
- /// <summary>
- /// 支持服务器主动向客户端推送消息
- /// </summary>
- private WebSocket webSocket;
-
- /// <summary>
- /// SocketIO管理对象
- /// </summary>
- private SocketManager socketManager;
-
-
- /// <summary>
- /// singalR通信对象
- /// </summary>
- private Connection singalRConnect;
-
-
- #region 一般Http请求,TCP连接
- /// <summary>
- /// Get请求:向特定的资源发出请求。
- /// </summary>
- /// <param name="url"></param>
- public HTTPRequest GetRequest(string url)
- {
- HTTPRequest request = new HTTPRequest(new Uri(url), OnRequestFinished);
- request.Send();
-
- return request;
- }
-
-
- /// <summary>
- /// Post请求:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。
- /// 数据被包含在请求体中。POST请求可能会导致新的资源的创建或已有资源的修改。
- /// </summary>
- /// <param name="url"></param>
- public HTTPRequest PostRequest(string url,Dictionary<string,string> paramDict = null)
- {
- HTTPRequest request = new HTTPRequest(new Uri(url),HTTPMethods.Post, OnRequestFinished);
-
- if (paramDict != null && paramDict.Count != 0)
- {
- foreach (KeyValuePair<string,string> v in paramDict)
- {
- request.AddField(v.Key, v.Value);
- }
- }
-
- request.Send();
-
- return request;
- }
-
- /// <summary>
- /// Head请求:向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。
- /// 这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。
- /// </summary>
- /// <param name="url"></param>
- public HTTPRequest HeadPost(string url)
- {
- HTTPRequest request = new HTTPRequest(new Uri(url),HTTPMethods.Head,OnRequestFinished);
- request.Send();
-
- return request;
- }
-
- /// <summary>
- /// Put请求:向指定资源位置上传其最新内容。
- /// </summary>
- /// <param name="url"></param>
- public HTTPRequest PutRequest(string url)
- {
- HTTPRequest request = new HTTPRequest(new Uri(url),HTTPMethods.Put,OnRequestFinished);
- request.Send();
-
- return request;
- }
-
- /// <summary>
- /// Delete请求:请求服务器删除 Request-URI 所标识的资源。
- /// </summary>
- /// <param name="url"></param>
- public HTTPRequest DeleteRequest(string url)
- {
- HTTPRequest request = new HTTPRequest(new Uri(url),HTTPMethods.Delete,OnRequestFinished);
- request.Send();
-
- return request;
- }
-
- /// <summary>
- /// Patch请求:是对 PUT 方法的补充,用来对已知资源进行局部更新 。
- /// </summary>
- /// <param name="url"></param>
- public HTTPRequest PatchRequest(string url)
- {
- HTTPRequest request = new HTTPRequest(new Uri(url),HTTPMethods.Patch,OnRequestFinished);
- request.Send();
-
- return request;
- }
-
-
- private void OnRequestFinished(HTTPRequest request, HTTPResponse response)
- {
- Debug.Log("Get 请求结果==" + response.DataAsText);
-
- if (response.StatusCode != 401)
- {
- Debug.Log("校验通过的");
- }
- else
- {
- Debug.Log("校验没通过的");
- }
- }
-
- #endregion
-
-
- #region 大文件Http请求
- private HTTPRequest StreamRequest(string url)
- {
- HTTPRequest request = new HTTPRequest(new Uri(url), OnStreamRequestFinished);
-
- //开启流式文件请求
- request.UseStreaming = true;
- request.StreamFragmentSize = 1 * 1024 * 1024;//1M
- //关闭缓存,因为已经将请求回来的数据保存到文件中
- request.DisableCache = true;
-
- request.Send();
-
- return request;
- }
-
- /// <summary>
- /// 大文件流式请求响应处理
- /// </summary>
- /// <param name="request"></param>
- /// <param name="response"></param>
- private void OnStreamRequestFinished(HTTPRequest request, HTTPResponse response)
- {
- List<byte[]> fragments = response.GetStreamedFragments();
- //下载的数据保存到文件中
- using (FileStream fs = new FileStream("pathToSave", FileMode.Append))
- {
- foreach (byte[] data in fragments)
- {
- fs.Write(data,0,data.Length);
- }
- }
-
- if (response.IsStreamingFinished)
- Debug.Log("大文件下载完毕!");
- }
- #endregion
-
-
- #region 大文件上传Http请求
- /// <summary>
- /// 大文件上传请求
- /// </summary>
- /// <param name="url"></param>
- /// <returns></returns>
- private HTTPRequest UpStreamRequest(string url)
- {
- HTTPRequest request = new HTTPRequest(new Uri(url),HTTPMethods.Post, OnUploadFinished);
- request.UploadStream = new FileStream("File_To.Upload",FileMode.Open);
- request.OnUploadProgress = OnUploadProgress;
- request.Send();
- return request;
- }
-
- /// <summary>
- /// 上传结束处理
- /// </summary>
- /// <param name="request"></param>
- /// <param name="response"></param>
- private void OnUploadFinished(HTTPRequest request, HTTPResponse response)
- {
- Debug.Log("文件上传结束!");
- }
-
- /// <summary>
- /// 上传进度回调
- /// </summary>
- /// <param name="request"></param>
- /// <param name="uploaded"></param>
- /// <param name="length"></param>
- private void OnUploadProgress(HTTPRequest request, long uploaded, long length)
- {
- float progressPercent = (uploaded / (float)length) * 100.0f;
- Debug.Log("文件上传进度: " + progressPercent.ToString("F2") + "%");
- }
-
- #endregion
-
-
- #region WebSocket
- /// <summary>
- /// WebSocket使用
- /// 一种双向通信协议,也是建立在TCP之上。
- /// </summary>
- /// <param name="url"></param>
- private void SetWebSocket(string url)
- {
- webSocket = new WebSocket(new Uri(url));
- webSocket.OnOpen += OnWebSocketOpen;
- webSocket.OnMessage += OnMessageReceived;
- webSocket.OnBinary += OnBinaryMessageReceived;
- webSocket.OnClosed += OnWebSocketClosed;
- webSocket.OnError += OnError;
- webSocket.OnErrorDesc += OnErrorDesc;
-
- webSocket.OnIncompleteFrame += OnIncompleteFrame;
-
- webSocket.Open();
- webSocket.Send("I am Winner!");
-
- byte[] buffer = new byte[1024];
- webSocket.Send(buffer);
-
-
- //webSocket.Close();
- }
-
- /// <summary>
- /// 连接建立的时候
- /// </summary>
- /// <param name="webSocket"></param>
- private void OnWebSocketOpen(WebSocket webSocket)
- {
- Debug.Log("WebSocket 打开!");
- }
-
- /// <summary>
- /// 接收服务器推送过来的消息
- /// </summary>
- /// <param name="webSocket"></param>
- /// <param name="message"></param>
- private void OnMessageReceived(WebSocket webSocket, string message)
- {
- Debug.Log("接收服务器推送过来的消息字符串: " + message);
- }
-
- /// <summary>
- /// 接收服务器推送的2进制消息
- /// </summary>
- /// <param name="webSocket"></param>
- /// <param name="message"></param>
- private void OnBinaryMessageReceived(WebSocket webSocket, byte[] message)
- {
- Debug.Log("接收服务器推送的2进制消息的长度: " + message.Length);
- }
-
- /// <summary>
- /// 连接关闭时
- /// </summary>
- /// <param name="webSocket"></param>
- /// <param name="code"></param>
- /// <param name="message"></param>
- private void OnWebSocketClosed(WebSocket webSocket, UInt16 code, string message)
- {
- Debug.Log("WebSocket 关闭!");
- }
-
- /// <summary>
- /// 连接异常时,报错
- /// </summary>
- /// <param name="ws"></param>
- /// <param name="ex"></param>
- private void OnError(WebSocket ws, Exception ex)
- {
- string errorMsg = string.Empty;
- if (ws.InternalRequest.Response != null)
- {
- errorMsg = string.Format("Status Code from Server: {0} and Message: {1}",
- ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message);
- }
-
- Debug.Log("错误发生: " + (ex != null ? ex.Message : "不明错误: " + errorMsg));
- }
-
- /// <summary>
- /// 报错
- /// </summary>
- /// <param name="ws"></param>
- /// <param name="error"></param>
- private void OnErrorDesc(WebSocket ws, string error)
- {
- Debug.Log("错误: " + error);
- }
-
-
- /// <summary>
- /// 针对大文本或2进制消息
- /// </summary>
- /// <param name="webSocket"></param>
- /// <param name="frame"></param>
- private void OnIncompleteFrame(WebSocket webSocket, WebSocketFrameReader frame)
- {
-
- }
-
- #endregion
-
- #region Socket.IO
- /// <summary>
- /// Socket.IO测试使用
- /// 提供了基于事件的实时双向通讯.将WebSocket和Polling机制以及其它的实时通信方式封装成通用的接口
- /// </summary>
- private void SetSocketIO(string url)
- {
- socketManager = new SocketManager(new Uri(url));
-
- //默认socket套接字获取
- Socket root = socketManager.Socket;
- //Socket nsp = socketManager["/customNamespace"];
- //Socket nsp2 = socketManager.GetSocket("/customNamespace");
-
- //服务器事件订阅
- socketManager.Socket.On("login", OnLogin);
- socketManager.Socket.On("connect", OnConnect);
- socketManager.Socket.On("connecting",OnConnecting);
- socketManager.Socket.On("customEvent",OnCustomEvent);
- socketManager.Socket.On("disconnect",OnDisconnect);
- socketManager.Socket.On("reconnect",OnReConnect);
- socketManager.Socket.On("reconnecting",OnReConnecting);
- socketManager.Socket.On("reconnect_attempt",OnAttemptToReConnect);
- socketManager.Socket.On("reconnect_failed",OnReconnectFailed);
- socketManager.Socket.On("error",OnError);
- socketManager.Socket.On(SocketIOEventTypes.Error,OnError);
-
- socketManager.Socket.On("frame",OnFrame);
- //不自动解码设置
- socketManager.Socket.On("frame2", OnFrame2,false);
- }
-
- private void ResetSocketIO()
- {
- //服务器事件取消
- socketManager.Socket.Off("login", OnLogin);
- socketManager.Socket.Off("connect", OnConnect);
- socketManager.Socket.Off("connecting", OnConnecting);
- socketManager.Socket.Off("customEvent", OnCustomEvent);
- socketManager.Socket.Off("disconnect", OnDisconnect);
- socketManager.Socket.Off("reconnect", OnReConnect);
- socketManager.Socket.Off("reconnecting", OnReConnecting);
- socketManager.Socket.Off("reconnect_attempt", OnAttemptToReConnect);
- socketManager.Socket.Off("reconnect_failed", OnReconnectFailed);
- socketManager.Socket.Off("error", OnError);
- socketManager.Socket.Off(SocketIOEventTypes.Error, OnError);
-
- socketManager.Socket.Off("frame", OnFrame);
- socketManager.Socket.Off("frame2", OnFrame2);
- }
-
-
- /// <summary>
- /// 向服务器发送请求
- /// </summary>
- /// <param name="eventName"></param>
- /// <param name="arg"></param>
- public void SocketIOReq(string eventName, params object[] arg)
- {
- socketManager.Socket.Emit(eventName,arg);
- }
-
- /// <summary>
- /// 向服务器发送请求,带回调
- /// </summary>
- /// <param name="eventName"></param>
- /// <param name="onServerCallBack"></param>
- /// <param name="arg"></param>
- public void SocketIOReq2(string eventName, OnServerCallBack onServerCallBack, params object[] args)
- {
- socketManager.Socket.Emit(eventName,onServerCallBack,args);
- }
-
-
- private Texture2D texture;
- /// <summary>
- /// 数据解析
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnFrame(Socket socket, Packet packet, params object[] args)
- {
- texture = new Texture2D(100,50);
- texture.LoadImage(packet.Attachments[0]);
- }
-
- /// <summary>
- /// 数据解析2
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnFrame2(Socket socket, Packet packet, params object[] args)
- {
- texture = new Texture2D(100, 50);
- texture.LoadImage(packet.Attachments[0]);
- }
-
- /// <summary>
- /// 登陆事件监听
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnLogin(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
- /// <summary>
- /// 连接
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnConnect(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
- /// <summary>
- /// 连接中
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnConnecting(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
- /// <summary>
- /// 任意的自定义事件
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnCustomEvent(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
- /// <summary>
- /// 连接断开时:传输断开,socketmanager关闭,socket关闭,无心跳消息返回等
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnDisconnect(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
- /// <summary>
- /// 重连上
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnReConnect(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
- /// <summary>
- /// 重连中
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnReConnecting(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
- /// <summary>
- /// 尝试重连
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnAttemptToReConnect(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
- /// <summary>
- /// 重连失败
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnReconnectFailed(Socket socket, Packet packet, params object[] args)
- {
-
- }
-
-
- /// <summary>
- /// 错误信息
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="packet"></param>
- /// <param name="args"></param>
- private void OnError(Socket socket, Packet packet, params object[] args)
- {
- Error error = args[0] as Error;
- switch (error.Code)
- {
- case SocketIOErrors.User:
- Debug.Log("Exception in an event handler!");
- break;
- case SocketIOErrors.Internal:
- Debug.Log("Internal error!");
- break;
- default:
- Debug.Log("Server error!");
- break;
- }
-
- Debug.Log(error.ToString());
- }
- #endregion
-
- #region SingalR
- /// <summary>
- /// SingalR实现实时通信
- /// </summary>
- public void SetSingalR(string url)
- {
- singalRConnect = new Connection(new Uri(url));
- singalRConnect.OnConnected += OnConnected;
- singalRConnect.OnClosed += OnClosed;
- singalRConnect.OnError += OnError;
- singalRConnect.OnReconnecting += OnReconnecting;
- singalRConnect.OnReconnected += OnReconnected;
- singalRConnect.OnStateChanged += OnStateChnaged;
- singalRConnect.OnNonHubMessage += OnNonHubMessage;
- singalRConnect.RequestPreparator += RequestPreparator;
-
- singalRConnect.Open();
- }
-
- /// <summary>
- /// 连接上了
- /// </summary>
- /// <param name="connection"></param>
- private void OnConnected(Connection connection)
- {
- Debug.Log("连接上了 SignalR server!");
- }
-
- /// <summary>
- /// 关闭的
- /// </summary>
- /// <param name="connection"></param>
- private void OnClosed(Connection connection)
- {
- Debug.Log("连接关闭");
- }
-
- /// <summary>
- /// 错误消息
- /// </summary>
- /// <param name="connection"></param>
- /// <param name="error"></param>
- private void OnError(Connection connection, string error)
- {
-
- }
-
- /// <summary>
- /// 重连中
- /// </summary>
- /// <param name="connection"></param>
- private void OnReconnecting(Connection connection)
- {
- Debug.Log("Reconnecting");
- }
-
- /// <summary>
- /// 重连上了
- /// </summary>
- /// <param name="connection"></param>
- private void OnReconnected(Connection connection)
- {
- Debug.Log("Reconnected");
- }
-
- /// <summary>
- /// 连接状态变化
- /// </summary>
- /// <param name="connection"></param>
- /// <param name="oldState"></param>
- /// <param name="newState"></param>
- private void OnStateChnaged(Connection connection, ConnectionStates oldState, ConnectionStates newState)
- {
- Debug.Log(string.Format("State Changed {0} -> {1}", oldState, newState));
- }
-
- /// <summary>
- /// NonHua消息监听
- /// </summary>
- /// <param name="connection"></param>
- /// <param name="data"></param>
- private void OnNonHubMessage(Connection connection, object data)
- {
- Debug.Log("Message from server: " + data.ToString());
- }
-
- /// <summary>
- /// 请求自定义
- /// </summary>
- /// <param name="connection"></param>
- /// <param name="req"></param>
- /// <param name="type"></param>
- private void RequestPreparator(Connection connection, HTTPRequest req, RequestTypes type)
- {
- req.Timeout = TimeSpan.FromSeconds(30);
- }
-
- /// <summary>
- /// 消息发送给服务器
- /// </summary>
- /// <param name="type"></param>
- /// <param name="value"></param>
- public void SendMsg(string type, string value)
- {
- singalRConnect.Send(new { Type = type, Value = value});
- }
-
- /// <summary>
- /// json格式发送:
- /// { Type: ‘Broadcast’, Value: ‘Hello SignalR World!’ }
- /// </summary>
- /// <param name="jsonStr"></param>
- public void SendMsg2(string jsonStr)
- {
- singalRConnect.SendJson(jsonStr);
- }
- #endregion
-
-
- void Awake()
- {
- //全局配置一些变量
- //和服务器的最大连接数设置
- HTTPManager.MaxConnectionPerServer = 4;
- //连接一次请求后是否还保持活跃
- HTTPManager.KeepAliveDefaultValue = false;
- //是否关闭缓存机制,默认开启
- HTTPManager.IsCachingDisabled = true;
- //连接完成了最后一次请求后,多长时间销毁
- HTTPManager.MaxConnectionIdleTime = TimeSpan.FromSeconds(20);
-
- //cookie机制是否开启
- HTTPManager.IsCookiesEnabled = true;
- HTTPManager.CookieJarSize = 10485760;
- //是否禁止cookie写到磁盘中
- HTTPManager.EnablePrivateBrowsing = false;
-
- //时间限制
- HTTPManager.ConnectTimeout = TimeSpan.FromSeconds(20);
- HTTPManager.RequestTimeout = TimeSpan.FromSeconds(60);
-
- //代理服务器
- HTTPManager.Proxy = new HTTPProxy(new Uri("http://localhost:3128"));
-
- //服务器证书校验
- HTTPManager.DefaultCertificateVerifyer = new CustomVerifier();
- HTTPManager.UseAlternateSSLDefaultValue = true;
- }
-
-
- // Use this for initialization
- void Start () {
-
- request1 = GetRequest("http://server.com/path");
- //根据连接请求使用情况,设置是否保持请求连接的活跃【默认:true】
- request1.IsKeepAlive = false;
- //关于是否缓存【默认:false】
- request1.DisableCache = false;
- //凭证【可选】
- request1.Credentials = new Credentials("userName","passwoed");
- //携带之前服务器认证成功生成的cookie如身份认证参数过去,方便访问。【可选】
- request1.Cookies.Add(new Cookie("Name","Value"));
- //代理服务器设置【可选】
- request1.Proxy = new HTTPProxy(new Uri("http://localhost:3128"));
- //下载进度回调设置【可选】
- request1.OnProgress = OnDownloadProgress;
- //与服务器建立连接的时间限制设定【可选】
- request1.ConnectTimeout = TimeSpan.FromSeconds(2);
- //与服务器请求到响应的总时间限制的设定【可选】
- request1.Timeout = TimeSpan.FromSeconds(10);
- //请求处理的优先级设置【可选】
- request1.Priority = -1;
- //服务器证书验证【可选】
- request1.CustomCertificateVerifyer = new CustomVerifier();
- request1.UseAlternateSSL = true;
- //重定向【可选】
- request1.OnBeforeRedirection += OnBeforeRedirect;
-
-
- 手动终止请求
- //request1.Abort();
-
-
- //一些统计数据
- GeneralStatistics statis = HTTPManager.GetGeneralStatistics(StatisticsQueryFlags.All);
- Debug.Log("[Connection] RequestsInQueue:" + statis.RequestsInQueue+ " Connections:"+statis.Connections
- + " ActiveConnections:"+statis.ActiveConnections+ " FreeConnections:"+statis.FreeConnections
- + " RecycledConnections:"+statis.RecycledConnections);
-
- Debug.Log("[Cache] CacheEntityCount:"+statis.CacheEntityCount+ " CacheSize:"+statis.CacheSize);
-
- Debug.Log("[Cookie] CookieCount:"+statis.CookieCount+ " CookieJarSize:"+statis.CookieJarSize);
-
-
- }
-
- /// <summary>
- /// 重定向处理:服务器无法处理客户端发送过来的请求(request),服务器告诉客户端跳转到可以处理请求的url上
- /// </summary>
- /// <param name="originalRequest"></param>
- /// <param name="response"></param>
- /// <param name="redirectUri"></param>
- /// <returns></returns>
- private bool OnBeforeRedirect(HTTPRequest originalRequest, HTTPResponse response, Uri redirectUri)
- {
- //状态码302时,做重定向处理
- if (response.StatusCode == 302)
- {
-
- }
-
- return true;
- }
-
- /// <summary>
- /// 下载进度回调
- /// </summary>
- /// <param name="request"></param>
- /// <param name="downloaded"></param>
- /// <param name="length"></param>
- private void OnDownloadProgress(HTTPRequest originalRequest, long downloaded, long downloadLength)
- {
- float progressPercent = (downloaded / (float)downloadLength) * 100.0f;
- Debug.Log("请求的下载速度: " + progressPercent.ToString("F2") + "%");
- }
-
-
- // Update is called once per frame
- void Update () {
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。