将 WebSocket 与 ASP.NET Web API2 结合使用

问题描述 投票:0回答:1

我在我的 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;
        }
    }

也许有人可以解释我的错误在哪里。

c# .net websocket asp.net-web-api2
1个回答
0
投票

浏览器通常会发送CORS 预检请求以查看服务器是否理解 CORS 协议。如果服务器不响应 CORS 标头,则该请求将被浏览器拒绝。

在本地环境中,您直接访问 ASP.NET 应用程序,因此一切正常。但对于 IIS(您的应用程序的反向代理),它可以响应请求,而无需向您的 ASP.NET 应用程序发出任何调用,这取决于如何配置 IIS 来托管您的应用程序。

我发现可以解决这个问题的最接近的东西在这个线程中描述:IIS hijacks CORS Preflight OPTIONS request

© www.soinside.com 2019 - 2024. All rights reserved.