我想在服务器端打开一个GET方法,它将简单地打开一个websocket到另一个web服务器,并作为客户端和另一个服务器之间的简单网关。
在客户端和第一个web服务器之间获得websocket是相当简单的,但我找不到如何轻松打开另一个并转发消息。请注意,我甚至不需要听客户端正在推送的内容:所有消息都来自第二个web服务器。
我设法写了下面的代码,这似乎是好的。既然我在这里问了这个问题,我就把我的代码贴出来。如有任何意见,我将不胜感激。
[Route("api/{slip}")]
[HttpGet]
public async Task<IHttpActionResult> TrackJob(String slip)
{
var serverEndpoint = string.Format("ws://{0}/api/services", slip);
HttpContext currentContext = HttpContext.Current;
if (currentContext.IsWebSocketRequest)
{
try
{
currentContext.AcceptWebSocketRequest(GetWebSocketSession(serverEndpoint));
return ResponseMessage(Request.CreateResponse(HttpStatusCode.SwitchingProtocols));
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw ex;
}
}
else
{
return NotFound();
}
}
private Func<AspNetWebSocketContext, Task> GetWebSocketSession(String serverEndpoint)
{
Func<AspNetWebSocketContext, Task> func = async (context) =>
{
var wsToClient = context.WebSocket;
using (var wsToProcessingCluster = new ClientWebSocket())
{
new Task(async () =>
{
var inputSegment = new ArraySegment<byte>(new byte[1024]);
while (true)
{
// MUST read if we want the state to get updated...
try
{
await wsToClient.ReceiveAsync(inputSegment, CancellationToken.None);
}
catch (Exception ex)
{
Console.WriteLine(ex);
return;
}
if (wsToClient.State != WebSocketState.Open)
{
await wsToProcessingCluster.CloseAsync(WebSocketCloseStatus.Empty, "", CancellationToken.None);
break;
}
}
}).Start();
var buffer = new byte[1024];
var uri = new Uri(serverEndpoint);
await wsToProcessingCluster.ConnectAsync(uri, CancellationToken.None);
while (true)
{
if (wsToClient.State != WebSocketState.Open)
{
break;
}
else
{
var segment = new ArraySegment<byte>(buffer);
var result = await wsToProcessingCluster.ReceiveAsync(segment, CancellationToken.None);
await wsToClient.SendAsync(segment, result.MessageType, result.EndOfMessage, CancellationToken.None);
}
}
}
};
return func;
}