首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET Application 與 Session 物件實作簡易聊天室 (WebForm 版)

     編輯:ASP.NET 基礎

利用 `Application` 儲存全域共享資料 (線上名單、聊天記錄、人數),`Session` 儲存個別使用者暱稱,配合 `Global.asax` 事件維護線上狀態,快速建立無 SignalR 依賴的傳統聊天室。

架構設計

  • Application["OnlineUsers"]:`Dictionary` Key=SessionId, Value=暱稱
  • Application["ChatLog"]:`StringBuilder` 累積聊天訊息
  • Application["UserCount"]:`int` 線上人數
  • Session["NickName"]:當前使用者暱稱

Global.asax 事件處理

public class Global : HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        Application["OnlineUsers"] = new Dictionary();
        Application["ChatLog"] = new StringBuilder();
        Application["UserCount"] = 0;
    }

    protected void Session_Start(object sender, EventArgs e)
    {
        Application.Lock();
        Application["UserCount"] = (int)Application["UserCount"] + 1;
        Application.UnLock();
    }

    protected void Session_End(object sender, EventArgs e)
    {
        string sessionId = Session.SessionID;
        Application.Lock();
        var users = (Dictionary)Application["OnlineUsers"];
        if (users.ContainsKey(sessionId)) users.Remove(sessionId);
        Application["UserCount"] = (int)Application["UserCount"] - 1;
        Application.UnLock();
    }
}

登入頁 Login.aspx

輸入暱稱進入聊天室

protected void BtnEnter_Click(object sender, EventArgs e)
{
    string nick = txtNick.Text.Trim();
    if (string.IsNullOrEmpty(nick))
    {
        lblErr.Text = "請輸入暱稱";
        return;
    }
    Session["NickName"] = nick;
    Response.Redirect("ChatRoom.aspx");
}

聊天室頁 ChatRoom.aspx

線上用戶 ()

protected void Page_Load(object sender, EventArgs e)
{
    if (Session["NickName"] == null) { Response.Redirect("Login.aspx"); return; }

    lblCount.Text = Application["UserCount"].ToString();

    if (!IsPostBack)
    {
        // 首次載入:將自己加入線上名單
        var users = (Dictionary)Application["OnlineUsers"];
        Application.Lock();
        users[Session.SessionID] = Session["NickName"].ToString();
        Application.UnLock();

        txtLog.Text = ((StringBuilder)Application["ChatLog"]).ToString();
    }

    // 每次載入重新綁定名單 (含其他人進出)
    lstUsers.DataSource = ((Dictionary)Application["OnlineUsers"]).Values;
    lstUsers.DataBind();
}

protected void BtnSend_Click(object sender, EventArgs e)
{
    string msg = txtMsg.Text.Trim();
    if (string.IsNullOrEmpty(msg)) return;

    string nick = Session["NickName"].ToString();
    var log = (StringBuilder)Application["ChatLog"];
    Application.Lock();
    log.AppendLine($"{DateTime.Now:HH:mm:ss} {nick}: {msg}");
    Application.UnLock();

    txtLog.Text = log.ToString();
    txtMsg.Text = "";
    // 維持捲軸在底部需客戶端 JS 配合
}

protected void BtnLeave_Click(object sender, EventArgs e)
{
    var users = (Dictionary)Application["OnlineUsers"];
    Application.Lock();
    users.Remove(Session.SessionID);
    Application["UserCount"] = (int)Application["UserCount"] - 1;
    Application.UnLock();

    Session.Abandon();
    Response.Redirect("Login.aspx");
}

關鍵技術點與限制

項目說明
Application.Lock/UnLock多執行緒環境下保護共享資料,防止競爭條件
StringBuilder 非執行緒安全鎖定期間操作,或改用 ConcurrentQueue + 定期刷新
Session_End 觸發條件僅 InProc 模式生效;StateServer/SQLServer 不觸發
即時更新本範例需手動重整或設定 ``;生產環境建議 SignalR
擴充性單機限制;Web Farm 需改用 Redis/資料庫共享狀態

現代化改造建議

  • 引入 SignalR:自動處理連線管理、即時推播、擴展至多伺服器。
  • 聊天記錄改存 **Redis List** 或 **資料庫**,支援分頁、搜尋、持久化。
  • 使用者狀態改用 **分散式 Session** 或 **JWT Token** 攜帶暱稱。
  • 前端改用 **Vue/React + SignalR Client**,提供豐富 UI (表情、圖片、回覆、@提及)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved