1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
4+ using System . Net ;
5+ using System . Text ;
6+ using System . Threading . Tasks ;
7+ using GameFrameX . Network . Runtime ;
8+ using GameFrameX . Runtime ;
9+ using ProtoBuf ;
10+ #if UNITY_WEBGL
11+ using UnityEngine . Networking ;
12+ #endif
13+
14+ namespace GameFrameX . Web . Runtime
15+ {
16+ /// <summary>
17+ /// Web请求管理器的ProtoBuf部分实现
18+ /// </summary>
19+ public partial class WebManager : GameFrameworkModule , IWebManager
20+ {
21+ /// <summary>
22+ /// 等待处理的Binary请求队列
23+ /// </summary>
24+ private readonly Queue < WebBinaryData > m_WaitingBinaryQueue = new Queue < WebBinaryData > ( 256 ) ;
25+
26+ /// <summary>
27+ /// 正在处理的Binary请求列表
28+ /// </summary>
29+ private readonly List < WebBinaryData > m_SendingBinaryList = new List < WebBinaryData > ( 16 ) ;
30+
31+ /// <summary>
32+ /// 更新处理ProtoBuf请求队列
33+ /// </summary>
34+ /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位</param>
35+ /// <param name="realElapseSeconds">真实流逝时间,以秒为单位</param>
36+ void UpdateBinary ( float elapseSeconds , float realElapseSeconds )
37+ {
38+ lock ( m_StringBuilder )
39+ {
40+ if ( m_SendingBinaryList . Count < MaxConnectionPerServer )
41+ {
42+ if ( m_WaitingBinaryQueue . Count > 0 )
43+ {
44+ var webBinaryData = m_WaitingBinaryQueue . Dequeue ( ) ;
45+
46+ MakeBinaryBytesRequest ( webBinaryData ) ;
47+
48+ m_SendingBinaryList . Add ( webBinaryData ) ;
49+ }
50+ }
51+ }
52+ }
53+
54+ /// <summary>
55+ /// 关闭ProtoBuf请求处理,清理资源
56+ /// </summary>
57+ private void ShutdownBinary ( )
58+ {
59+ while ( m_WaitingBinaryQueue . Count > 0 )
60+ {
61+ var webData = m_WaitingBinaryQueue . Dequeue ( ) ;
62+ webData . Dispose ( ) ;
63+ }
64+
65+ m_WaitingBinaryQueue . Clear ( ) ;
66+ while ( m_SendingBinaryList . Count > 0 )
67+ {
68+ var webData = m_SendingBinaryList [ 0 ] ;
69+ m_SendingBinaryList . RemoveAt ( 0 ) ;
70+ webData . Dispose ( ) ;
71+ }
72+
73+ m_SendingBinaryList . Clear ( ) ;
74+
75+ m_MemoryStream . Dispose ( ) ;
76+ }
77+
78+ /// <summary>
79+ /// 执行ProtoBuf字节请求
80+ /// </summary>
81+ /// <param name="webData">ProtoBuf请求数据</param>
82+ private async void MakeBinaryBytesRequest ( WebBinaryData webData )
83+ {
84+ #if UNITY_WEBGL
85+ UnityWebRequest unityWebRequest ;
86+ if ( webData . IsGet )
87+ {
88+ unityWebRequest = UnityWebRequest . Get ( webData . URL ) ;
89+ }
90+ else
91+ {
92+ unityWebRequest = UnityWebRequest . Post ( webData . URL , string . Empty ) ;
93+ }
94+
95+ unityWebRequest . timeout = ( int ) RequestTimeout . TotalSeconds ;
96+ {
97+ byte [ ] postData = webData . SendData ;
98+ unityWebRequest . uploadHandler = new UploadHandlerRaw ( postData ) ;
99+ }
100+
101+ var asyncOperation = unityWebRequest . SendWebRequest ( ) ;
102+ asyncOperation . completed += ( asyncOperation2 ) =>
103+ {
104+ m_SendingBinaryList . Remove ( webData ) ;
105+ if ( unityWebRequest . isNetworkError || unityWebRequest . isHttpError || unityWebRequest . error != null )
106+ {
107+ webData . Task . TrySetException ( new Exception ( unityWebRequest . error ) ) ;
108+ return ;
109+ }
110+
111+ webData . Task . SetResult ( new WebBufferResult ( webData . UserData , unityWebRequest . downloadHandler . data ) ) ;
112+ } ;
113+ #else
114+ try
115+ {
116+ HttpWebRequest request = WebRequest . CreateHttp ( webData . URL ) ;
117+ request . Method = webData . IsGet ? WebRequestMethods . Http . Get : WebRequestMethods . Http . Post ;
118+ request . Timeout = ( int ) RequestTimeout . TotalMilliseconds ; // 设置请求超时时间
119+ byte [ ] postData = webData . SendData ;
120+ request . ContentLength = postData . Length ;
121+ using ( Stream requestStream = request . GetRequestStream ( ) )
122+ {
123+ await requestStream . WriteAsync ( postData , 0 , postData . Length ) ;
124+ }
125+
126+ using ( HttpWebResponse response = ( HttpWebResponse ) await request . GetResponseAsync ( ) )
127+ {
128+ using ( Stream responseStream = response . GetResponseStream ( ) )
129+ {
130+ m_MemoryStream . SetLength ( response . ContentLength ) ;
131+ m_MemoryStream . Position = 0 ;
132+ await responseStream . CopyToAsync ( m_MemoryStream ) ;
133+ webData . Task . SetResult ( new WebBufferResult ( webData . UserData , m_MemoryStream . ToArray ( ) ) ) ; // 将流的内容复制到内存流中并转换为byte数组
134+ }
135+ }
136+ }
137+ catch ( WebException e )
138+ {
139+ // 捕获超时异常
140+ if ( e . Status == WebExceptionStatus . Timeout )
141+ {
142+ webData . Task . SetException ( new TimeoutException ( e . Message ) ) ;
143+ return ;
144+ }
145+
146+ webData . Task . SetException ( e ) ;
147+ }
148+ catch ( IOException e )
149+ {
150+ webData . Task . SetException ( e ) ;
151+ }
152+ catch ( Exception e )
153+ {
154+ webData . Task . SetException ( e ) ;
155+ }
156+ finally
157+ {
158+ m_SendingBinaryList . Remove ( webData ) ;
159+ }
160+ #endif
161+ }
162+
163+
164+ /// <summary>
165+ /// 发送字节数组Post请求,返回字节数组结果
166+ /// </summary>
167+ /// <param name="url">请求地址</param>
168+ /// <param name="from">要发送的字节数组数据</param>
169+ /// <param name="queryString">URL查询参数字典</param>
170+ /// <param name="header">HTTP请求头字典</param>
171+ /// <param name="userData">用户自定义数据</param>
172+ /// <returns>返回WebBufferResult类型的异步任务</returns>
173+ public Task < WebBufferResult > PostToBytes ( string url , byte [ ] from , Dictionary < string , string > queryString , Dictionary < string , string > header , object userData = null )
174+ {
175+ var uniTaskCompletionSource = new TaskCompletionSource < WebBufferResult > ( ) ;
176+ url = UrlHandler ( url , queryString ) ;
177+ var webData = new WebBinaryData ( url , from , uniTaskCompletionSource , userData ) ;
178+ m_SendingBinaryList . Add ( webData ) ;
179+ MakeBinaryBytesRequest ( webData ) ;
180+ return uniTaskCompletionSource . Task ;
181+ }
182+ }
183+ }
0 commit comments