我在我的网站上建立了一个非常简单的聊天页面,这是我到目前为止所拥有的:
这是代码:
<asp:Content ID="Content2" ContentPlaceHolderID="maincontent" Runat="Server">
<script language="javascript" type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args) {
document.getElementById('<%=FormView1.FindControl("chattxt").ClientID%>').focus();
}
</script>
<div id="chatbg">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div id="chatmessages">
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<asp:Literal ID="Literal1" runat="server" Text='<%# Eval("Username") %>'></asp:Literal>: <asp:Literal ID="Literal2" runat="server" Text='<%# Eval("Message") %>'></asp:Literal><br />
</ItemTemplate>
</asp:Repeater>
</div>
<asp:ListBox ID="ListBox1" runat="server" Rows="16" CssClass="memberlist"></asp:ListBox>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:FormView ID="FormView1" runat="server" DefaultMode="Insert"
OnItemInserted="fv_ItemInserted" RenderOuterTable="False"
DataSourceID="SqlDataSource1">
<InsertItemTemplate>
<asp:Panel ID="Panel1" runat="server" DefaultButton="Button1">
<asp:TextBox ID="chattxt" runat="server" CssClass="chattxtbox"
Text='<%# Bind("Message") %>' autocomplete="off"></asp:TextBox>
<asp:Button ID="Button1" runat="server" CommandName="insert" style="display:none" Text="Button"/>
</asp:Panel>
</InsertItemTemplate>
</asp:FormView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:orangefreshConnectionString1 %>"
InsertCommand="INSERT INTO [Chat] ([Username], [Message]) VALUES (@Username, @Message)"
SelectCommand="SELECT [Id], [Username], [Message], [Date] FROM [Chat] ORDER BY [Id]" >
<InsertParameters>
<asp:Parameter Name="Message" Type="String" />
<asp:Parameter Name="Date" Type="DateTime" />
<asp:SessionParameter Name="Username" SessionField="Username" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
<script type="text/javascript">
function scrollpos() {
var objDiv = document.getElementById("chatmessages");
objDiv.scrollTop = objDiv.scrollHeight;
}
</script>
</asp:Content>
这是我的代码隐藏:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
using orangefreshModel;
public partial class chat : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
Session["Username"] = User.Identity.Name;
ListBox1.Items.Clear();
foreach (MembershipUser myuser in Membership.GetAllUsers())
if (myuser.IsOnline == true)
{
ListBox1.Items.Add(myuser.ToString());
}
ScriptManager.RegisterStartupScript(
UpdatePanel1,
this.GetType(),
"ScrollPos",
"scrollpos();",
true);
}
protected void fv_ItemInserted(object sender, FormViewInsertedEventArgs e)
{
this.FormView1.DataBind();
}
}
所以这一切都运行得很好,UpdatePanel确保我的消息立即弹出,现在的问题是看到其他用户消息。这是我的第一个ASP.NET项目,所以我考虑过稍微讨厌它,每隔一秒尝试一次Timer来重新填充我的中继器......但是没有成功,我认为它不是明智的解决方案:
首先,影响我的Repeater窗口的Timer使得用户无法向上滚动以阅读消息,因为每次滚动时刷新都是不可能的。
其次,我从来没有让它工作,这是我为我的计时器尝试的事件:
protected void Timer1_Tick(object sender, EventArgs e)
{
this.Repeater1.DataSource = SqlDataSource1;
this.Repeater1.DataBind();
}
但是,没有成功。
这就是我现在正在聊聊的地方:我可以看到我的消息弹出正常,但现在我需要找到一种方法让我的窗口更新,因为其他用户输入他们的消息,如果有的话其他用户输入新消息,我需要发送自己的消息才能看到他们的消息。
我一直在浏览网页,阅读了一些关于Signal R的内容,但我想知道是否有人对我应该去哪里有更简单的想法,如何在我的消息上实现实时更新窗口?
答案 0 :(得分:2)
我建议调查SignalR - http://nuget.org/packages/signalr
SignalR是一个保持持久连接打开的库,允许服务器将数据“推送”到客户端。
您还可以将http://www.slideshare.net/adammokan/introduction-to-signalr-10082193视为SignalR的理想概述
它
答案 1 :(得分:1)
一种选择是在ASP.Net生命周期之外执行此操作,并向服务器发出手动AJAX请求。服务器方法可以保持连接最多30秒,一旦到达就返回任何新消息。然后将其返回给客户端并在JS中处理,然后他们打开另一个连接并再次等待。我听说这叫做reverse AJAX poll
。
但是,您检测到新消息取决于您,您可以每秒轮询数据库,或维护内存消息等。
请注意,如果数千个客户端保持与服务器的开放连接,则可能会出现问题。
答案 2 :(得分:1)
我同意KingPancake的意见,SignalR将是一个非常好的方法来接近这样的事情。如果您希望保留数据,可以使用新的.Net Web API和SignalR“后端”这样做
查看Brad Wilson的this presentation,这可能会对您有所帮助:
答案 3 :(得分:1)
SignalR是个不错的选择。
但是,如果您确实想出于某种原因自己动手,那么就应该采用这种方式。
在asp.net中构建聊天的最有效方法是使用IHttpAsyncHandler和ajax请求。
异步请求允许您延迟请求的响应,直到发生外部事件 用户调用此处理程序并等待有人向他发送消息 邮件会在您发送给用户后立即发送。
收到消息后,客户端发出另一个请求并等待下一条消息。 这是保持持久连接打开的方式,并允许服务器将数据推送到客户端。
这比查看网站以检查邮件是否已到达要高效得多 使用异步处理程序还可确保在用户等待消息到来时不会浪费任何asp.net线程。使用计时器进行轮询,您将很快用完线程来处理asp.net中的请求。
这确保即使网站的用户数量增加,您的聊天也可以很好地扩展。