我在我的 Intranet 中使用我的 webapi 工作正常,并停用了任何 cors 策略,因为我不需要它们。
现在我还想在我的 iis 应用程序中添加一个 websocket,但是在运行它时,只有 localhost 可以正常工作,并且所有其他请求都会出现 cors 错误
Global.asax.cs:
public class WebApiApplication : System.Web.HttpApplication
{
private static readonly ILogger Logger = Log.ForContext<WebApiApplication>();
protected void Application_Start()
{
Logger.Debug("In Application_Start");
EnableCorsAttribute corsAttribute = new EnableCorsAttribute("*", "*", "*");
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configuration.EnableCors(corsAttribute);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// NEW PART START:Add WebSocket route handler
string baseAddress = "http://*:9999/websocket/";
HttpListener listener = new HttpListener();
listener.Prefixes.Add(baseAddress);
listener.Start();
// Handle WebSocket upgrade requests
listener.BeginGetContext(HandleWebSocketRequest, listener);
//NEW PART END
Logger.Information("App started !");
}
// NEW PART
private async Task HandleWebSocket(HttpListenerContext context)
{
HttpListenerWebSocketContext webSocketContext = null;
try
{
webSocketContext = await context.AcceptWebSocketAsync(subProtocol: null);
// WebSocket connection established
WebSocket webSocket = webSocketContext.WebSocket;
// Handle WebSocket communication
await HandleWebSocketCommunication(webSocket);
}
catch (Exception ex)
{
// Handle WebSocket upgrade exception
Console.WriteLine($"WebSocket upgrade error: {ex.Message}");
if (webSocketContext != null)
{
webSocketContext.WebSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "Internal Server Error", CancellationToken.None).Wait();
}
}
}
// NEW PART
private async Task HandleWebSocketCommunication(WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
try
{
while (webSocket.State == WebSocketState.Open)
{
// Receive a message from the client
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Text)
{
// Handle text message
string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
Console.WriteLine($"Received message: {message}");
// React to the received message
await ReactToMessage(webSocket, message);
}
else if (result.MessageType == WebSocketMessageType.Close)
{
// Handle close message
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
}
}
}
catch (WebSocketException ex)
{
// Handle WebSocket communication exception
Console.WriteLine($"WebSocket communication error: {ex.Message}");
}
finally
{
// Close WebSocket connection
if (webSocket.State == WebSocketState.Open)
{
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
}
webSocket.Dispose();
}
}
// NEW PART
private async Task ReactToMessage(WebSocket webSocket, string message)
{
// Implement your logic to react to the received message
// For example, you could process the message and send a response back to the client
string responseMessage = $"Received your message: {message}";
byte[] responseBuffer = Encoding.UTF8.GetBytes(responseMessage);
await webSocket.SendAsync(new ArraySegment<byte>(responseBuffer), WebSocketMessageType.Text, true, CancellationToken.None);
}
// NEW PART
private void HandleWebSocketRequest(IAsyncResult result)
{
HttpListener listener = (HttpListener)result.AsyncState;
HttpListenerContext context = listener.EndGetContext(result);
if (context.Request.IsWebSocketRequest)
{
// Upgrade HTTP connection to WebSocket
HandleWebSocket(context);
}
else
{
// Handle other HTTP requests
// For example, you can return a 404 response
context.Response.StatusCode = 404;
context.Response.Close();
}
// Continue listening for incoming requests
listener.BeginGetContext(HandleWebSocketRequest, listener);
}
protected void Application_End(object sender, EventArgs e)
{
Logger.Debug("In Application_End");
ApplicationShutdownReason shutdownReason = System.Web.Hosting.HostingEnvironment.ShutdownReason;
}
}
也许有人可以解释我的错误在哪里。
浏览器通常会发送CORS 预检请求以查看服务器是否理解 CORS 协议。如果服务器不响应 CORS 标头,则该请求将被浏览器拒绝。
在本地环境中,您直接访问 ASP.NET 应用程序,因此一切正常。但对于 IIS(您的应用程序的反向代理),它可以响应请求,而无需向您的 ASP.NET 应用程序发出任何调用,这取决于如何配置 IIS 来托管您的应用程序。
我发现可以解决这个问题的最接近的东西在这个线程中描述:IIS hijacks CORS Preflight OPTIONS request