2

在创建聊天系统期间,我使用 long life request 来获取消息,并使用 jquery 请求来发送消息,如下所示:

*发送: *

$("#btn").click(function () { 
    $.ajax({
        type: "POST",
        url: "Chat.aspx/Insert",
        data: "{ 'Str' :'" + $("#txtStr").val() + "' }",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
        },
        error: function () {

        }
    });
});

收到 :

function Refresh() {

    $.ajax({
        type: "POST",
        url: "Chat.aspx/GetRecords",
        data: "{ 'Id' : " + $("#hdnV1").val() + "}",
        success: function (data) {

            $.each($(data.d), function () {

               //Show it to user

            });

        },
        complete: function () {
            return Refresh();
        },

        contentType: "application/json; charset=utf-8",
        dataType: "json",
        traditional: true,
        async: true
    });

}

这是我获取消息的服务器端代码:

[WebMethod]
public static object GetRecords(int Id)
{
    TestEntities db = new TestEntities();
    int count = 0;
    while (true)
    {
        if (count++ >= 300)
            return null;


        System.Threading.Thread.Sleep(1000);
        var list = db.Commets.Where(rec => rec.Id > Id).Select(rec => new { Id = rec.Id, Str = rec.Str }).ToList();

        if (list.Count > 0)
            return list;

    }
}

当用户写东西并点击发送按钮时,请求进入挂起状态,我的事情是因为长寿命请求正在执行

我在萤火虫中检查它们,有没有人可以帮助我!?!更多细节请评论我,对不起我的英语语法不好,我是英语新手

谢谢

4

4 回答 4

4

这不是在 asp.net 中建立聊天的最佳方法。随着用户数量的增加,此方法将无法扩展。

看看SignalR是构建聊天应用程序的好选择。

但是,如果您出于某种原因确实想自己做,在 asp.net 中构建聊天的最有效方法是使用IHttpAsyncHandler和 ajax 请求。

Asp.net 的工作线程数量有限。让其中一个进入睡眠状态只会杀死您的应用程序,即使对于相对较少的用户也是如此。

异步请求允许您延迟请求的响应,直到发生外部事件。
用户调用此处理程序并等待有人向他发送消息。
一旦您将消息发送给用户,它们就会被传递。

收到消息后,客户端发出另一个请求并等待下一条消息。这就是保持持久连接打开并允许服务器将数据推送到客户端的方式。

这比轮询站点以检查消息是否到达要有效得多。
使用异步处理程序还可以确保在用户等待消息到来时不会浪费任何 asp.net 线程。使用计时器轮询您将很快用完线程来处理 asp.net 中的请求。

这可以确保即使网站的用户数量增加,您的聊天也可以很好地扩展。

这是一个与 ajax 一起实现这个的完全工作的项目。

避免使用数据库作为您网站上用户之间的通信方式。如果要记录聊天记录,请进行所有写入异步调用。

于 2012-09-11T04:25:34.787 回答
1

由于您在评论中写道您正在Session应用程序中使用状态,因此长时间运行的请求阻止更新可能是正确的。

原因是 Asp.Net 阻止了对Session. 有关详细信息,请参阅MSDN 上的此链接。具体(靠近页面底部):

但是,如果对同一个会话发出两个并发请求(通过使用相同的 SessionID 值),则第一个请求将获得对会话信息的独占访问权。第二个请求仅在第一个请求完成后执行。

解决它的一种方法可能是设置EnableSessionState="ReadOnly"EnableSessionState="False"在有问题的页面上。这假设您不需要使用Session聊天系统访问特定页面中的 。

于 2012-09-10T12:35:10.980 回答
0

您也应该异步发送插入,就像使用 GetRecords 一样。那应该可以解决您的问题。添加async: true到发送请求。

于 2012-08-03T08:30:19.950 回答
0

问题是GetRecords可能永远不会回来。除非您使用 WebSockets 之类的东西,否则这是一个问题。这意味着连接永远不会完成(直到超时),您很可能不会收到任何数据。

你应该做的是GetRecords立即返回,然后每隔 X 秒在你的 jQuery 中轮询新记录。

您还可以尝试Sleep在 while 循环中添加一个(以及最大循环限制)以允许其他线程在系统中工作并防止无限循环。IE

int maxLoops = 50;
int loopNum = 0;
while (loopNum < maxLoops)
{
        var list = db.Commets.Where(rec => rec.Id > Id).Select(rec => new { Id = rec.Id, Str = rec.Str }).ToList();

        if (list.Count > 0)
            return list;

        Thread.Sleep(250); //Wait 1/4 of a second
        loopNum++;
}
于 2012-08-03T08:32:46.960 回答