AJAX 简单聊天
一个简单的 AJAX 和 C# .NET 聊天程序。轻量级,不需要任何 Applet 或服务器!
引言
这是一个用 C# 实现的简单的基于 AJAX 的聊天程序。
说明
重要提示:这是一个为 ASP.NET 2.0 (VS2005 或更高版本) 制作的聊天程序。
- 在您的解决方案中添加一个新的 Web 表单,将其命名为 ChatPage.aspx,选择 C# 语言。
- 将页面 HTML 复制并粘贴到 Web 表单的源代码视图中。
- 将页面代码复制并粘贴到 Web 表单的代码隐藏文件中,文件名为 ChatPage.aspx.cs。
- 将业务逻辑复制并粘贴到您的 App_Code 文件夹中的一个新类中,命名为 SPilafisChatLogic.cs。
- 将 AJAX for ASP.NET 2.0 (VS2005) 添加到您的解决方案中。(使用 VS2005,只需将 DLL 拖放到您的 bin 文件夹中,并在您的 web.config 文件中添加几行代码。)
- 来点薯条,享受吧!
页面 HTML
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="ChatPage.aspx.cs" Inherits="ChatPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head id="Head1" runat="server">
<title>Chat Ajax .NET</title>
<style type="text/css">
td {
font-family: Arial;
font-size: 8pt;
}
</style>
<!--
License and Disclaimer: All the intructions, code, html and everything
presented with this solution is provided 'as is' with no warranties what so ever.
The only condition for you to use this software is that you keep the link
to http://www.spilafis.com.ar in the chat page as provided.
Please support freeware keeping the link and clicking on my sponsors.
Thank you!
!-->
</head>
<body>
<form id="form1" runat="server" onsubmit="return false;">
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<table align="center" width="732"
border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<textarea id="txtChatFrame" runat="server"
rows="15"
style="width:527px; border:1px solid #aaaaaa; padding:4px;"
readonly="readonly"></textarea><br/>
</td>
<td valign="top">
<div style="overflow: auto; height: 226px; border-top:
solid 2px gray; border-bottom: solid 2px gray;
border-right: solid 1px gray; border-left: solid 1px gray; ">
<asp:GridView ID="grvUsers" runat="server"
AutoGenerateColumns="False" BackColor="White"
BorderColor="#DEDFDE" BorderStyle="None"
BorderWidth="1px" CellPadding="1"
ForeColor="Black"
GridLines="Vertical" Height="30px">
<FooterStyle BackColor="#CCCC99" />
<Columns>
<asp:BoundField HeaderText="User"
ReadOnly="True" DataField="ChatUsers">
<ItemStyle Width="110px" />
<HeaderStyle Height="10px" />
</asp:BoundField>
<asp:BoundField HeaderText="Last Activity"
DataField="ChatLastActivity">
<ItemStyle Width="190px" />
<HeaderStyle Height="10px" />
</asp:BoundField>
</Columns>
<RowStyle BackColor="#F7F7DE" />
<SelectedRowStyle BackColor="#CE5D5A"
Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#F7F7DE"
ForeColor="Black" HorizontalAlign="Right" />
<HeaderStyle BackColor="#6B696B"
Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
</div>
<input id="btnRefresh" runat="server"
type="submit" onclick="document.forms['form1'].submit();"
value="Refresh"
style="cursor:pointer;border:1px solid gray; height: 15px;
width: 100%; font-size: 7pt;"
size="20"/>
</td>
</tr>
<tr>
<td>
<table border="0" cellpadding="0"
cellspacing="5" style="width:527px;">
<tr>
<td align="right" valign="middle">Message: </td>
<td align="left" style="height: 45px" valign="top">
<table border="0" cellpadding="0" cellspacing="2">
<tr>
<td><textarea cols="70" rows="2"
id="txtMssg"
style="border:1px solid gray; width: 370px; height: 37px;"
onkeyup="SendByKey(event.keyCode);"></textarea></td>
<td><input id="btnSend" type="button"
value="Send" onclick="Send()"
style="cursor:pointer;border:1px solid gray;
height: 42px;"/></td>
</tr>
</table></td>
</tr>
<tr>
<td align="right" valign="middle"
style="width:70px">User Name: </td>
<td align="left">
<table border="0"
cellpadding="0" cellspacing="2">
<tr>
<td><input id="txtName" type="text"
maxlength="10"
style="border:1px solid #aaaaaa; width: 145px;"
onblur="ChangeUserName(this);"/
value="<%=SpilafisChatLogic.Chat.GetUserName()%>" />
</td>
<td>
Get source code!:
<a href="http://www.spilafis.com.ar">
http://www.spilafis.com.ar</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td valign="middle">
<br />
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td align="center">Users Writing: <br />
(max. <%=SpilafisChatLogic.Chat.MaxLoggedInUsers.ToString()%>)
</td>
<td align="right"><span id="spnW">0</span> <br /><br /></td>
</tr>
<tr>
<td colspan="2"> <br /></td>
</tr>
<tr>
<td align="left">Users Reading: </td>
<td align="right"><span id="spnR">0</span></td>
</tr>
</table>
</td>
</tr>
</table>
<br />
<br />
<script type="text/javascript" language="javascript">
function ChangeUserName(otxtName)
{
var tentative_name = otxtName.value;
if(tentative_name=="")
alert("You must enter a user name to be able to chat.");
else
{
if(tentative_name!=last_user_name)
{
var otxtMssg = document.getElementById("txtMssg");
var obtnSend = document.getElementById("btnSend");
var ret = Chat.ChangeUserName(tentative_name);
if(ret!=null && ret.error!=null && ret.error!="")
{
otxtName.value = last_user_name;
alert(new String(ret.error).replace("System.Exception ",""));
}
else
{
last_user_name = otxtName.value;
obtnSend.disabled = false;
otxtMssg.disabled = false;
otxtMssg.focus();
}
}
}
}
function Send()
{
var otxtName = document.getElementById("txtName");
if(otxtName.value!="")
{
var otxtMssg = document.getElementById("txtMssg");
if(!otxtMssg.disabled)
{
var ret = Chat.Post(otxtMssg.value);
if(ret!=null && ret.error!=null)
{
alert(new String(ret.error).replace("System.Exception ",""));
}
otxtMssg.value = "";
otxtMssg.focus();
}
}
else
{
if(!otxtName.disabled)
{
alert("Enter a user name");
otxtName.focus();
}
}
}
function SendByKey(keycode)
{
if (keycode == 13)
Send();
event.returnValue = false;
}
var cycles = 20;
var add_wait_cycles = 20;
var reload_wait = 700;
var last_user_name = "";
var max_chat_lines = <%=SpilafisChatLogic.Chat.MaxChatLines%>;
function Reload()
{
var ret;
cycles++;;
if(cycles>=add_wait_cycles)
{
cycles = 0;
// Get users writing
ret = Chat.GetUsersWriting();
if(ret!=null && (ret.error==null || ret.error=="") &&
ret.value!=null && ret.value!="")
document.getElementById("spnW").innerHTML = ret.value;
// Get users reading
ret = Chat.GetUsersReading();
if(ret!=null && (ret.error==null || ret.error=="") &&
ret.value!=null && ret.value!="")
document.getElementById("spnR").innerHTML = ret.value;
}
// If not logged in to write then try to logg in the user
var otxtMssg = document.getElementById("txtMssg");
if(otxtMssg.disabled)
{
var otxtName = document.getElementById("txtName");
if(otxtName.value=="")
{
ret = Chat.GetNextUserName();
if(ret!=null && ret.error==null &&
ret.value!=null && ret.value!="")
{
otxtName.value = ret.value;
LoggedIn();
alert("You have been logged in");
}
}
else
{
last_user_name = otxtName.value;
otxtMssg.disabled = false;
var obtnSend = document.getElementById("obtnSend");
obtnSend.disabled = false;
otxtMssg.focus();
}
}
// Read Chat
var ret = Chat.Read();
if(ret!=null && ret.error!=null)
{
alert("A critical error ocurred: " + new String(ret.error).replace(
"System.Exception ","") +
"\nPlease reload page to try again.");
return;
}
var value = ret.value;
if(value!=null && value!="")
{
var otxtChatFrame =
document.getElementById("<%=txtChatFrame.ClientID%>");
var already_read = otxtChatFrame.value;
//var all = value + already_read;
var all = already_read + value;
if(all!="")
{
var arr = all.split("\n");
if(arr.length>max_chat_lines)
{
all = "";
//for(var i=0; i<max_chat_lines; i++)
for(var i=(arr.length-max_chat_lines); i<arr.length; i++)
all += arr[i] + "\n";
}
}
otxtChatFrame.value = all;
// Scroll down to the last read line
otxtChatFrame.scrollTop=otxtChatFrame.scrollHeight;
}
window.setTimeout("Reload();", reload_wait);
}
function Start()
{
Reload();
// Initial scroll down to the last read line (in case Refresh is hit)
var otxtChatFrame = document.getElementById("<%=txtChatFrame.ClientID%>");
otxtChatFrame.scrollTop=otxtChatFrame.scrollHeight;
}
function LoggedIn()
{
var otxtName = document.getElementById("txtName");
var obtnSend = document.getElementById("btnSend");
var otxtMssg = document.getElementById("txtMssg");
last_user_name = otxtName.value;
otxtName.disabled = false;
obtnSend.disabled = false;
otxtMssg.disabled = false;
otxtMssg.focus();
}
// Call to start!
Start();
</script>
</form>
</body>
</html>
页面代码隐藏
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using System.Globalization;
/// <summary>
/// License and Disclaimer: All the intructions, code, html
/// and everything presented with this solution
/// is provided 'as is' with no warranties what so ever.
/// The only condition for you to use this software is that
/// you keep the link to http://www.spilafis.com.ar in the chat page
/// as provided. Please support freeware keeping the link and clicking on my sponsors.
/// Thank you!
/// </summary>
public partial class ChatPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Register AJAX
Ajax.Utility.RegisterTypeForAjax(typeof(SpilafisChatLogic.Chat));
UpdateUsersGridView();
}
public void UpdateUsersGridView()
{
// Update grid
grvUsers.DataSource = SpilafisChatLogic.Chat.GetUsersDataSource();
grvUsers.DataBind();
}
protected void btnRefresh_ServerClick(object sender, EventArgs e)
{
UpdateUsersGridView();
}
}
业务逻辑
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using System.Globalization;
namespace SpilafisChatLogic
{
/// <summary>
/// License and Disclaimer: All the intructions, code, html
/// and everything presented with this solution
/// is provided 'as is' with no warranties what so ever.
/// The only condition for you to use this software is that you keep
/// the link to http://www.spilafis.com.ar in the chat page as provided.
/// Please support freeware keeping the link and clicking on my sponsors.
/// Thank you!
/// </summary>
public class Business
{
public Business()
{
}
public static User CurrentUser
{
get
{
if (HttpContext.Current.Session["ChatCurrentUser"] == null)
HttpContext.Current.Session["ChatCurrentUser"] = new User();
return (User)HttpContext.Current.Session["ChatCurrentUser"];
}
set
{
HttpContext.Current.Session["ChatCurrentUser"] = value;
}
}
public static App CurrentApp
{
get
{
if (HttpContext.Current.Application["ChatCurrentApp"] == null)
HttpContext.Current.Application["ChatCurrentApp"] = new App();
return (App)HttpContext.Current.Application["ChatCurrentApp"];
}
set
{
HttpContext.Current.Application["ChatCurrentApp"] = value;
}
}
}
public class User
{
#region Private Members
private bool m_ajax_chat_counted;
private string m_ajax_chat_user_name;
private int m_ajax_chat_last_read_id;
private bool m_code_access_enabled;
#endregion
public User()
{
m_ajax_chat_counted = false;
m_ajax_chat_user_name = "";
m_ajax_chat_last_read_id = -1;
m_code_access_enabled = false;
}
#region Properties
public bool AjaxChatCounted
{
get { return m_ajax_chat_counted; }
set { m_ajax_chat_counted = value; }
}
public string AjaxChatUserName
{
get { return m_ajax_chat_user_name; }
set { m_ajax_chat_user_name = value; }
}
public int AjaxChatLastReadId
{
get { return m_ajax_chat_last_read_id; }
set { m_ajax_chat_last_read_id = value; }
}
#endregion
}
public class App
{
#region Private Members
private int m_ajax_chat_users_r;
private Hashtable m_ajax_chat_users_w;
private Hashtable m_ajax_chat_users_w_last_activity;
private ArrayList m_ajax_chat;
#endregion
public App()
{
m_ajax_chat_users_w = new Hashtable();
m_ajax_chat_users_w_last_activity = new Hashtable();
m_ajax_chat = new ArrayList();
}
#region Properties
public int AjaxChatUsersR
{
get { return m_ajax_chat_users_r; }
set { m_ajax_chat_users_r = value; }
}
public Hashtable AjaxChatUsersW
{
get { return m_ajax_chat_users_w; }
set { m_ajax_chat_users_w = value; }
}
public Hashtable AjaxChatUsersWLastActivity
{
get { return m_ajax_chat_users_w_last_activity; }
set { m_ajax_chat_users_w_last_activity = value; }
}
public ArrayList AjaxChat
{
get { return m_ajax_chat; }
set { m_ajax_chat = value; }
}
#endregion
}
public class Chat
{
#region Constants
public static int MaxMessageLength = 100;
public static int MaxChatLines = 50;
public static int MaxLoggedInUsers = 5;
public static string[] BadWords = { "a**hole",
"boludo"}; // Add your bad word dictionary here
#endregion
public Chat()
{
}
#region Methods
private static void IncrementUsersReading()
{
Business.CurrentApp.AjaxChatUsersR = GetIntUsersReading() + 1;
}
private static int GetIntUsersReading()
{
return Business.CurrentApp.AjaxChatUsersR;
}
private static int GetId(string message)
{
return Convert.ToInt32(message.Split('-')[0]);
}
private static string GetMessage(string message)
{
return message.Split('-')[1];
}
private static string GetNextId(ArrayList ajax_chat_list)
{
int id = GetMaxId(ajax_chat_list);
if (id < Int32.MaxValue)
id++;
else
id = 0;
return id.ToString() + "-";
}
private static int GetMaxId(ArrayList ajax_chat_list)
{
if (ajax_chat_list.Count > 0)
return GetId(ajax_chat_list[0].ToString());
else
return 0;
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static string GetUserName()
{
if (Business.CurrentUser.AjaxChatUserName == "")
Chat.GetNextUserName();
return Business.CurrentUser.AjaxChatUserName;
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static string GetNextUserName()
{
string user_name = "";
// Count user reading if not counted yet
if (!Business.CurrentUser.AjaxChatCounted)
{
Business.CurrentUser.AjaxChatCounted = true;
IncrementUsersReading(); // Is decremented in session end
}
else
{
if (Business.CurrentUser.AjaxChatUserName != null &&
Business.CurrentUser.AjaxChatUserName != "")
return Business.CurrentUser.AjaxChatUserName;
}
int user_number = Business.CurrentApp.AjaxChatUsersW.Count + 1;
// If user may log in
if (user_number <= MaxLoggedInUsers)
{
// Get first not used guest user name
while (Business.CurrentApp.AjaxChatUsersW["ChatGuest" +
user_number.ToString()] != null)
{
if (user_number < int.MaxValue)
user_number++;
else
return "";
}
// Add to writing users list
Business.CurrentApp.AjaxChatUsersW.Add("Guest" +
user_number.ToString(), 1);
// Save user name to session
Business.CurrentUser.AjaxChatUserName =
"Guest" + user_number.ToString();
UpdateUserLastActivityTime();
}
return user_name;
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static void ChangeUserName(string tentative_name)
{
if (Business.CurrentUser.AjaxChatUserName == "")
{
int user_number = Business.CurrentApp.AjaxChatUsersW.Count + 1;
// If user may not log in inform
if (user_number > MaxLoggedInUsers)
throw new Exception("Max. number of writing " +
"users reached. You'll be inform when someone leaves.");
}
tentative_name = tentative_name.Trim();
if (tentative_name == "")
throw new Exception("You must enter a user name to be able to chat.");
if (tentative_name.IndexOf('-') >= 0)
throw new Exception("Character '-' is not allowed in the user name.");
if (tentative_name.Length > 10)
tentative_name = tentative_name.Substring(0, 10);
// If exists inform
if (Business.CurrentApp.AjaxChatUsersW[tentative_name] != null)
throw new Exception("User name already in use. Please enter another.");
// Remove old user name from the list
// Add to writing users list
ChangeUserNameInWList(tentative_name);
// Save user name to session
Business.CurrentUser.AjaxChatUserName = tentative_name;
UpdateUserLastActivityTime();
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static void ChangeUserNameInWList(string new_name)
{
// If it already had a user name then remove from writing users
if (Business.CurrentUser.AjaxChatUserName != null &&
Business.CurrentUser.AjaxChatUserName != "")
{
Business.CurrentApp.AjaxChatUsersW.Remove(
Business.CurrentUser.AjaxChatUserName);
// If it had a saved last activity time remove it
Business.CurrentApp.AjaxChatUsersWLastActivity.Remove(
Business.CurrentUser.AjaxChatUserName);
// Add to writing users list
Business.CurrentApp.AjaxChatUsersW.Add(new_name, 1);
// NOTE: It is not necessary to add it to the last activity
// table because it will be added after this
}
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static void Post(string message)
{
// Cut max message length
message = message.Trim();
if (message.Length > MaxMessageLength)
message = message.Substring(0, MaxMessageLength);
if (message != "")
{
// Add time and nickname to identify message
string message_head =
Business.CurrentUser.AjaxChatUserName + " says: ";
message = message_head + message;
ValidateMessage(Business.CurrentApp.AjaxChat, message);
// Add message id
message = GetNextId(Business.CurrentApp.AjaxChat) + message;
// Insert new message
Business.CurrentApp.AjaxChat.Insert(0, message);
// Delete lines after MaxChatLines
while (Business.CurrentApp.AjaxChat.Count > MaxChatLines)
Business.CurrentApp.AjaxChat.RemoveAt(
Business.CurrentApp.AjaxChat.Count - 1);
UpdateUserLastActivityTime();
}
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static void ValidateMessage(ArrayList ajax_chat_list, string message)
{
int index;
// Create array list of chat without message numbers
ArrayList ajax_chat_nonumbers = new ArrayList();
for (index = 0; index < ajax_chat_list.Count; index++)
ajax_chat_nonumbers.Add(ajax_chat_list[index].ToString().Split('-')[1]);
// Check for spam
if (ajax_chat_nonumbers.Contains(message))
throw new Exception("Please no spam...");
// Create message words array
string[] m_w = message.Replace("\n", " ").Replace("\r", "").Split(' ');
ArrayList message_words = new ArrayList();
for (index = 0; index < m_w.Length; index++)
message_words.Add(m_w[index]);
// Check for bad words
for (index = 0; index < BadWords.Length; index++)
if (message_words.Contains(BadWords[index]))
throw new Exception("Please no bad words...");
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static void UpdateUserLastActivityTime()
{
if (Business.CurrentUser.AjaxChatUserName != null &&
Business.CurrentUser.AjaxChatUserName != "")
UpdateUserLastActivityTime(
Business.CurrentApp.AjaxChatUsersWLastActivity);
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static void UpdateUserLastActivityTime(
Hashtable ajax_chat_users_w_last_activity)
{
if (ajax_chat_users_w_last_activity<Business.CurrentUser.AjaxChatUserName>
== null)
ajax_chat_users_w_last_activity.Add(
Business.CurrentUser.AjaxChatUserName, DateTime.Now);
else
ajax_chat_users_w_last_activity<
Business.CurrentUser.AjaxChatUserName> = DateTime.Now;
}
public static DataTable GetUsersDataSource()
{
// Create data source
DataTable dtSource = new DataTable();
dtSource.Columns.Add(new DataColumn("ChatUsers"));
dtSource.Columns.Add(new DataColumn("ChatLastActivity"));
DataRow drSource;
DateTime last_activity;
if (Business.CurrentApp.AjaxChatUsersW.Keys.Count > 0)
{
// Add list of users to datasource
foreach (object key in Business.CurrentApp.AjaxChatUsersW.Keys)
{
drSource = dtSource.NewRow();
drSource["ChatUsers"] = key.ToString();
// Get last activity time
if (Business.CurrentApp.AjaxChatUsersWLastActivity[key] != null)
{
last_activity =
(DateTime)Business.CurrentApp.AjaxChatUsersWLastActivity[key];
// Convert to GMT time
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
string dateFormat =
CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern.Replace(
"'GMT'", "zzz");
string dateString = last_activity.ToString(dateFormat);
drSource["ChatLastActivity"] = dateString;
}
else
drSource["ChatLastActivity"] = "<none>";
dtSource.Rows.Add(drSource);
}
}
else
{
drSource = dtSource.NewRow();
drSource["ChatUsers"] = "<none>";
drSource["ChatLastActivity"] = "<none>";
dtSource.Rows.Add(drSource);
}
// Sort by user name
dtSource.DefaultView.Sort = "ChatUsers";
return dtSource;
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static string Read()
{
int id;
int max_id = 0;
string message;
// Create chat list if not created
System.Text.StringBuilder chat = new System.Text.StringBuilder();
// Get chat from application level
ArrayList ajax_chat_list = Business.CurrentApp.AjaxChat;
// Get last read id from user session if already saved
int last_read_id = Business.CurrentUser.AjaxChatLastReadId;
// Write it to a string
int index;
ArrayList chat_arr = new ArrayList();
for (index = 0; index < ajax_chat_list.Count; index++)
{
id = GetId(ajax_chat_list[index].ToString());
if (index == 0)
max_id = id;
message = GetMessage(ajax_chat_list[index].ToString());
// If last read message read reached then stop reading
if (id == last_read_id)
break;
// Note: Why not "<="?
// Because "<=" may cause stop of reading
// Example: If last message read is 9, and then the id 10 message was sent
// and then the id message 1 was sent,
// first message read would be id 1 that is < than 9
// and wouldn't be read although it should be
// (if read, comparing just equal,
// then id 10 would be read and in 9 it would stop)
chat_arr.Add(System.Web.HttpUtility.HtmlEncode(message) + "\n");
//chat.Append(Server.HtmlEncode(message) + "\n");
}
// Build inverted order chat string
for (index = chat_arr.Count - 1; index >= 0; index--)
chat.Append(chat_arr[index].ToString());
// Set max_id as new last_read_id to user session
Business.CurrentUser.AjaxChatLastReadId = max_id;
UpdateUserLastActivityTime();
// Return chat string to user with max_id to set as new last_read_id
return chat.ToString();
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static string GetUsersWriting()
{
return Business.CurrentApp.AjaxChatUsersW.Count.ToString();
}
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.ReadWrite)]
public static string GetUsersReading()
{
return GetIntUsersReading().ToString();
}
#endregion
}
}
在这里查看一个可用的示例:http://spilafis.com.ar/ChatPage.aspx。
或者一个更复杂(相同的代码但增强)但更好用的示例:http://spilafis.com.ar/ChatAjaxNet.aspx。
许可和免责声明
此页面中提供的所有说明、代码、HTML 以及其他所有内容均按“原样”提供,不提供任何形式的保证。您使用此软件的唯一条件是,您在聊天页面中保留指向 http://www.spilafis.com.ar 的链接,如提供的页面所示。请支持免费软件,保留链接。