簡體   English   中英

在經典 asp.net forms 應用程序中使用 websockets

[英]Using websockets in classic asp.net forms application

我需要將 websocket 功能添加到遺留 asp.net webforms 應用程序(只是一個簡單的長時間工作流,從舊的小程序功能轉換而來)。

我天真地試圖將 websocket 處理程序添加到 aspx 頁面:

        public override void ProcessRequest(HttpContext context)
        {
            if (context.IsWebSocketRequest)
            {
                context.AcceptWebSocketRequest(HandleWebSocket);
            } else
            {
                base.ProcessRequest(context);
            }
        }

並在 IIS 上啟用 websocket: 在此處輸入圖像描述 然后嘗試: var ws = new WebSocket("ws://localhost/APP/Page.aspx"); 但這並不能正常工作。

不確定這是否可能?

我是否遺漏了有關配置或實施的內容? 我可以將 websocket 放在單獨的應用程序/服務器上,但更願意將其保存在一個可以訪問相同 session object 的位置。

應該可以在經典的 ASP.NET Forms 應用程序中處理 web 套接字連接。 這些工具在HttpContext上可用,您的想法基本上是正確的。

我認為問題在於您正試圖從aspx頁面調用它,而不僅僅是使用通用的IHttpHandler IIS 根據文件擴展名運行特定的處理管道。 Aspx相當專門用於嘗試呈現 HTML 頁面,因此雖然可以重新配置 IIS 以允許 websockets 與 ASPX 頁面交互,但僅使用通用的ashx處理程序要容易得多。

您可以通過轉到 Visual Studio 中的“添加項目”對話框來創建處理程序突出顯示“通用處理程序”條目的 Visual Studio 的“添加項目”對話框

此時,您只需在處理程序代碼中實現 websocket 邏輯。 我從這個 as.net 示例中放入一個簡單的回顯只是為了演示。

public class MyHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.IsWebSocketRequest)
        {
            context.AcceptWebSocketRequest(EchoWebSocket);
        }
    }

    private async Task EchoWebSocket(AspNetWebSocketContext socketContext)
    {
        var buffer = new byte[1024 * 4];
        var result = await socketContext.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

        while (!result.CloseStatus.HasValue)
        {
            await socketContext.WebSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
            result = await socketContext.WebSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        }

        await socketContext.WebSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

您現在應該能夠連接到 websocket。請注意wss而不是ws的用法。 我測試的設置需要安全版本 (wss)。 使用與您正在處理的應用程序相關的任何內容。

// Replace with port/path to your handler.
var ws = new WebSocket("wss://localhost:44336/MyHandler.ashx");

ws.onmessage = function(evt) { 
    console.log(evt); 
};

ws.send("Hello, World!");

您應該會看到類似於以下內容的 output: 帶有上述示例 javascript 輸出的 Chrome 開發人員控制台。

注意:我通常不建議嘗試從 websocket 處理程序訪問 Session 數據。 您的 session 可能會在 websocket 的生命周期之外到期。 您可能希望使用其他一些機制在套接字和頁面的 rest 之間保留 state(可能是數據庫或應用程序級緩存,您可以在上面的示例中從socketContext.Cache訪問它。

編輯:添加了在套接字初始化中使用 session 值的示例。 根據您的評論,如果您想在 websocket 的初始化期間使用 session 值(這應該是一個安全操作),那么您的處理程序只需要實現IRequiresSessionState並需要添加一些額外的語法以將 session 值傳遞給接受處理程序。

public class MyHandler : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.IsWebSocketRequest)
        {
            var sessionValue = context.Session["session_key"] as string;

            context.AcceptWebSocketRequest(async (socketContext) =>
            {
                await SetupWebSocket(socketContext, sessionValue);
            });
        }
    }

    private async Task SetupWebSocket(AspNetWebSocketContext socketContext, string sessionValue)
    {
        // Handle socket as before, but 'sessionValue' is now available for use.
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM