我想知道使用ServiceStack构建代理服务有多困难。考虑到ServiceStack与Redis /序列化等的速度有多快,以及一般实现堆栈的简单程度,这看起来非常诱人。有人试过这个吗?这有多难?
答案 0 :(得分:6)
在Proxy Feature中添加了一个新的ServiceStack v4.5.10,极大地简化了创建代理的过程,只需注册一个插件即可创建代理,例如:
Plugins.Add(new ProxyFeature(
matchingRequests: req => req.PathInfo.StartsWith("/proxy"),
resolveUrl:req => $"http://remote.server.org" + req.RawUrl.Replace("/proxy","/"))
{
// Use TransformResponse to rewrite response returned
TransformResponse = async (res, responseStream) =>
{
using (var reader = new StreamReader(responseStream, Encoding.UTF8))
{
var responseBody = await reader.ReadToEndAsync();
var replacedBody = responseBody.Replace(
"http://remote.server.org",
"https://external.domain.com/proxy");
return MemoryStreamFactory.GetStream(replacedBody.ToUtf8Bytes());
}
}
})
将ServiceStack实例中/proxy
的所有请求填充到http://remote.server.org
。
ServiceStack's Request Pipeline中的第一个条目允许您注册Raw ASP.NET IHttpHandlers,它可以执行原始ASP.NET处理程序并接管来自ServiceStack的请求。
这将允许您通过将其注册到AppHost来使用use an ASP.NET IHttpHandler proxy like this,例如:
this.RawHttpHandlers.Add(httpReq =>
httpReq.PathInfo.StartsWith("/proxy")
? new ReverseProxy()
: null);
这将告诉ServiceStack使用自定义ReverseProxy IHttpHandler执行以/proxy
开头的请求。
如果你想在ServiceStack的自托管中使用它,你还必须将ReverseProxy改为继承ServiceStack方便的HttpAsyncTaskHandler
基类(或只是实现IServiceStackHandler),例如:
public class ReverseProxy : HttpAsyncTaskHandler
{
public override void ProcessRequest(IRequest req, IResponse res,
string operationName)
{
var httpReq = (IHttpRequest)req; //Get HTTP-specific Interfaces
var httpRes = (IHttpResponse)res;
// Create a connection to the Remote Server to redirect all requests
var server = new RemoteServer(httpReq, httpRes);
// Create a request with same data in navigator request
HttpWebRequest request = server.GetRequest();
// Send the request to the remote server and return the response
HttpWebResponse response = server.GetResponse(request);
byte[] responseData = server.GetResponseStreamBytes(response);
// Send the response to client
res.ContentType = response.ContentType;
res.OutputStream.Write(responseData, 0, responseData.Length);
server.SetContextCookies(response); // Handle cookies to navigator
res.EndHttpHandlerRequest(); // End Request
}
public override void ProcessRequest(HttpContextBase context)
{
var httpReq = context.ToRequest("CustomAction");
ProcessRequest(httpReq, httpReq.Response, "CustomAction");
}
....
}
您还必须在示例中重构RemoteServer的实现,以使用ServiceStack的IHttpRequest
/ IHttpResponse
接口。
如果需要,您还可以使用以下命令访问基础ASP.NET(或HttpListener)请求对象:
var aspNetReq = httpReq.OriginalRequest as HttpRequestBase;
var aspNetRes = httpRes.OriginalResponse as HttpResponseBase;