耗时很长的服务器端事件中让客户端得到中间过程信息的合理解决方案

简介: 需求:B/S结构的系统里,用户点一个按钮系统开始发送上千封邮件,要求把发送信息(发送成功数,失败数,剩余数量...)动态实时的反馈给客户.   分析和实施过程当中遇到的问题:     一:最低级的问题由于客户催的紧,发邮件的核心代码写好后就开始给他使用了,当时系统还没上AJAX.

需求:
B/S结构的系统里,用户点一个按钮系统开始发送上千封邮件,要求把发送信息(发送成功数,失败数,剩余数量...)动态实时的反馈给客户.

 

分析和实施过程当中遇到的问题:

 

 

一:最低级的问题
由于客户催的紧,发邮件的核心代码写好后就开始给他使用了,当时系统还没上AJAX.

最初的问题是一点按钮过不了几分钟就页面超时(要想页面不超时必须定时给页面输出一些东西),
搞定了页面超时的问题然后就是服务器IIS超时
设置了IIS超时时间就又SQL连接超时

最后寻思这样下去总不是个办法
决定上ajax(正如大家想的一样)

 

 

二:开始想到了ajax
上ajax又碰到一个问题
ICallbackEventHandler只提供了两个方法,
一个是被客户端触发的服务器端事件,

一个是服务器端事件完成后的反馈事件
两个事件是顺序发生的,

我如果在一个事件中执行发送邮件的过程,

我就不能在这个事件中把中间过程的信息反馈给客户
我的两个需求必须同时进行!
我甚至想到:当用户点按钮的时候同时触发ajax事件和postback事件,

多么愚蠢的idea啊(回发了还怎能异步刷新)
最后:多方求助+苦思冥想最后得出两种解决方案

1.通过ajax每次发送一定数量的邮件
用javascript循环把邮件地址发送给服务器端(以ajax方式),

每循环一次给服务器端10条信息,

服务器端把这10个邮件发完之后,反馈客户端一次

客户端通过js更新提示信息(已经发完十封了)
然后进入下一次ajax循环

 

2.ajax调用服务器端事件,在服务器端事件里使用多线程技术
当用户点按钮触发了ajax服务器端事件后,

在这个事件里我建立了两个线程
一个线程开始发送邮件,另一个线程负责返回信息

因为要实时的返回信息,

所以这个ajax事件肯定是定时调用的.(我是每4秒获取一下服务器端的信息)
服务器端事件开始执行,

先判断发邮件的线程是否已经开始了,

如果没开始就建立发邮件的线程,

并执行线程
如果开始了(那么说明这个调用肯定不是第一次调用)
就执行反馈信息的代码

两种方案都是可行的,我最终选择了第二种

想法随好,在实施过程中又碰到了N多问题

 

 三.实施过程中的问题
1.假如在发送过程中用户出现了断网,或者不小心关闭了页面,我怎么让他下次登陆的时候继续发送.

在这里我想到了消息队列,事务等,最终的解决方案是
开始发邮件前先把所有待发的邮件存储到数据库的一个临时表里去,

发一封删除一条记录,

pagelodad里检测该表是否有记录,

如果有记录就直接发送该表里的邮件(也就是尚未完成的邮件)

这里可以用Page.ClientScript.RegisterStartupScript注册一个客户端事件调用我们的ajax函数


2.线程的参数问题

发送邮件的线程方法是肯定需要参数的,然而new Thread(new ThreadStart());创建线程的又不允许给线程传参数,

这个问题没有困绕我很久,因为网上有很多解决方案,比如建立一些public的变量或者属性

我用的是另外一种办法,先建立一个对象,然后给这个对象的属性负值(这就是我的参数啦)

然后创建线程的时候线程的方法是这个对象的一个方法sendmail_thread = new Thread(new ThreadStart(sendobj.sendmail_xuan));


3.线程开始状态判断的误区
线程有一个ThreadState属性,我不建议用这个属性的IsAlive判断线程是否开始.
因为代码执行到sendmail_thread = new Thread(new ThreadStart(sendobj.sendmail_xuan));这句后,

线程并不一定处于IsAlive状态,因为他要等服务器的CPU给他分配时间片(具体的我就不说了)
我是用session判断的

 

4.还是线程的问题

当用户执行了操作,有可能发送邮件的线程还没有开始,而ajax已经去取返回信息了.
(如果计算发送成功率,有可能造成除以0的错误)
或者邮件发送线程已经完成了操作,但ajax还一直在那取后端的反馈信息

(如果反馈发送消耗时间,有可能时间会一直增长)

人们都说网页上的多线程不好搞(每个访问就有可能造成一个线程)

果然如此啊,我这里还没考虑高并发的问题,

然而上面说的那两个问题都不是硬伤,

想想办法还是可以"掩饰"过去的

 

文章就写到这,我没有公布原代码,只是写了一些思想和解决方法

实在是我这个案例有点偏了.大家如果一定要原代码,那么就在此文章下留言吧

如果要的人超过10个我就写这个文章的续

 

另:系统开发过程中得到了Jeffrey Zhao  joseph.zhu(asp.net第一步的作者)  南洋 的帮助   在此表示感谢

8.19日为了阅读方便,我对文章做了一些修改,主要内容未变

目录
相关文章
|
4月前
|
移动开发 JavaScript 前端开发
精通服务器推送事件(SSE)与 Python 和 Go 实现实时数据流 🚀
服务器推送事件(SSE)是HTML5规范的一部分,允许服务器通过HTTP向客户端实时推送更新。相比WebSocket,SSE更轻量、简单,适合单向通信场景,如实时股票更新或聊天消息。它基于HTTP协议,使用`EventSource` API实现客户端监听,支持自动重连和事件追踪。虽然存在单向通信与连接数限制,但其高效性使其成为许多轻量级实时应用的理想选择。文中提供了Python和Go语言的服务器实现示例,以及HTML/JavaScript的客户端代码,帮助开发者快速集成SSE功能,提升用户体验。
|
3月前
|
Go API 定位技术
MCP 实战:用 Go 语言开发一个查询 IP 信息的 MCP 服务器
随着 MCP 的快速普及和广泛应用,MCP 服务器也层出不穷。大多数开发者使用的 MCP 服务器开发库是官方提供的 typescript-sdk,而作为 Go 开发者,我们也可以借助优秀的第三方库去开发 MCP 服务器,例如 ThinkInAIXYZ/go-mcp。 本文将详细介绍如何在 Go 语言中使用 go-mcp 库来开发一个查询 IP 信息的 MCP 服务器。
233 0
|
3月前
|
人工智能 搜索推荐 程序员
用 Go 语言轻松构建 MCP 客户端与服务器
本文介绍了如何使用 mcp-go 构建一个完整的 MCP 应用,包括服务端和客户端两部分。 - 服务端支持注册工具(Tool)、资源(Resource)和提示词(Prompt),并可通过 stdio 或 sse 模式对外提供服务; - 客户端通过 stdio 连接服务器,支持初始化、列出服务内容、调用远程工具等操作。
1068 4
|
3月前
|
存储 监控 API
【Azure App Service】分享使用Python Code获取App Service的服务器日志记录管理配置信息
本文介绍了如何通过Python代码获取App Service中“Web服务器日志记录”的配置状态。借助`azure-mgmt-web` SDK,可通过初始化`WebSiteManagementClient`对象、调用`get_configuration`方法来查看`http_logging_enabled`的值,从而判断日志记录是否启用及存储方式(关闭、存储或文件系统)。示例代码详细展示了实现步骤,并附有执行结果与官方文档参考链接,帮助开发者快速定位和解决问题。
131 23
|
4月前
|
网络协议 开发者 Python
Socket如何实现客户端和服务器间的通信
通过上述示例,展示了如何使用Python的Socket模块实现基本的客户端和服务器间的通信。Socket提供了一种简单且强大的方式来建立和管理网络连接,适用于各种网络编程应用。理解和掌握Socket编程,可以帮助开发者构建高效、稳定的网络应用程序。
175 10
|
6月前
|
存储 开发工具 git
[Git] 深入理解 Git 的客户端与服务器角色
Git 的核心设计理念是分布式,每个仓库既可以是客户端也可以是服务器。通过 GitHub 远程仓库和本地仓库的协作,Git 实现了高效的版本管理和代码协作。GitHub 作为远程裸仓库,存储项目的完整版本历史并支持多客户端协作;本地仓库则通过 `.git` 文件夹独立管理版本历史,可在离线状态下进行提交、回滚等操作,并通过 `git pull` 和 `git push` 与远程仓库同步。这种分布式特性使得 Git 在代码协作中具备强大的灵活性和可靠性。
151 18
[Git] 深入理解 Git 的客户端与服务器角色
|
7月前
|
存储 人工智能 自然语言处理
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
ChatMCP 是一款基于模型上下文协议(MCP)的 AI 聊天客户端,支持多语言和自动化安装。它能够与多种大型语言模型(LLM)如 OpenAI、Claude 和 OLLama 等进行交互,具备自动化安装 MCP 服务器、SSE 传输支持、自动选择服务器、聊天记录管理等功能。
2178 16
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
|
8月前
|
弹性计算 监控 容灾
阿里云ECS提供强大的云上灾备解决方案,通过高可用基础设施、多样的数据备份方式及异地灾备服务,帮助企业实现业务的持续稳定运行
在数字化时代,企业对信息技术的依赖加深,确保业务连续性至关重要。阿里云ECS提供强大的云上灾备解决方案,通过高可用基础设施、多样的数据备份方式及异地灾备服务,帮助企业实现业务的持续稳定运行。无论是小型企业还是大型企业,都能从中受益,确保在面对各种风险时保持业务稳定。
201 4
|
8月前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
146 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
8月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
4139 2

热门文章

最新文章