用HttpListener开发HTTP服务器靠谱吗?

a435648445 2014-12-31 08:32:44
最近做一个项目,只是用来提供API接口,感觉没必要用IIS,所以就想到用HttpListener做一个Windows服务来实现,但不知道这样有没有什么问题,长时间运行会不会内存越占越多,然后能承载多少用户访问
...全文
5766 12 打赏 收藏 举报
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
config_man 2017-08-17
学习学习学习学习学习学习学习学习
  • 打赏
  • 举报
回复
baidu_27549073 2017-03-23
学习了,原来还有HttpListener这种东西
  • 打赏
  • 举报
回复
kusirp21 2015-01-24
顺便说一下多线程设计原则,诚然,多线程为防止线程丢失等内存泄露现象,不允许“面条调用”,也说是说,线程要做到统一管理,一般只在主业务线程中开辟,使用,或回收。尽量不出现线程中调用线程的情况,包括TPL也尽量不要违反。否则线程调用线程,线程再调用线程,无法做到统一管理。国内称该种调用为面条,该术语在SP时代,由于不同函数相互调用,有大牛说是象一碗意大利面而闻称。所以线程里调线程,本身就不合适。如果线程只是空调一下,那只是纯粹逗你玩的!
  • 打赏
  • 举报
回复
kusirp21 2015-01-24
建议使用IIS来做,性能差别不大。稳定性较好,因为你已经将协议选择到了http上。除非你使用项目使用基础的tcp协议时才可能建议你用服务或控制台去做。 IIS优势:稳定性,安全性均可照顾到,支持并发,又能将程序员从复杂的多线程编程中解放出来。 服务要使用多线程,且要考虑数据同步等相关信息,使用线程池,日志等需要手工实现。编程量稍大,开发周期稍长。 所以如果你选用http协议的话,建议使用IIS。 IIS编程时请使用IHttpModule在请求到达的第一个事件BeginRequest时直接进行处理,处理完毕后使用Reponse.End()直接触发管线中的最后一个事件EndRequest。这样可以达到的性能并不比服务差。 但良好的服务不出现内存泄露等问题,但如果不好的代码的话可能性能还不及IIS。 如果定义为低层的协议,则直接使用Lister监听连接端口,如果为了达到高效,可考虑使用缓冲池,监听池来处理请求。所以使用控制台方便编程,同时又可有良好的性能,抗击较高的请求压力。为防止用户注销,考虑使用系统用户SYSTEM运行控制台程序即可达到与服务相同的效果(需加开机启动)。
  • 打赏
  • 举报
回复
饕餮123 2015-01-24
有wcf为什么不用?可以selfhost
  • 打赏
  • 举报
回复
a435648445 2015-01-02
引用 6 楼 sp1234 的回复:
你可以使用系统线程池,例如
private static void MainProcess(IAsyncResult ar)
{
    var context = listener.EndGetContext(ar);
    listener.BeginGetContext(MainProcess, null);
    ThreadPool.QueueUserWorkItem(h =>
    {
        var response = context.Response;
        response.AddHeader("Server", "My Server V0.0.1");
        var request = context.Request;
       ........
可以是用 request.InputSteam 读取 post 来的 json 输入命令的等等,常见的 web 服务的简单输入输出,可以自己把握。 如果要接收复杂的参数,例如实现 Rfc 2396 格式的 post 数据,或许需要写100行代码。这已经算是很麻烦的了。而且这种东西不需要写几个。 平常自己写的高性能的服务器端代码,就是固定模式的输入输出,就跟写过 console 程序一样简单。
好的,谢谢~~~ 但能走到MainProcess这个方法已经是另一条线程了又使用ThreadPool.QueueUserWorkItem开一条线程来处理是不是有一点多辞一举?
  • 打赏
  • 举报
回复
你可以使用系统线程池,例如
private static void MainProcess(IAsyncResult ar)
{
    var context = listener.EndGetContext(ar);
    listener.BeginGetContext(MainProcess, null);
    ThreadPool.QueueUserWorkItem(h =>
    {
        var response = context.Response;
        response.AddHeader("Server", "My Server V0.0.1");
        var request = context.Request;
       ........
可以是用 request.InputSteam 读取 post 来的 json 输入命令的等等,常见的 web 服务的简单输入输出,可以自己把握。 如果要接收复杂的参数,例如实现 Rfc 2396 格式的 post 数据,或许需要写100行代码。这已经算是很麻烦的了。而且这种东西不需要写几个。 平常自己写的高性能的服务器端代码,就是固定模式的输入输出,就跟写过 console 程序一样简单。
  • 打赏
  • 举报
回复
实际上,如果你的某些 web 开发方式将前后端进行很大的分离,那么整个 asp.net 里边的所有复杂的UI生成代码基本上你都不需要,而它的性能慢得,就好像北京有个土豪每天早高峰时间开着坦克去送孩子上学,为了99%不需要的功能而付出性能代价是不值当的。你至少可以在asp.net服务程序之外,再有个自己的 web服务程序,保证更灵活和更高性能。
  • 打赏
  • 举报
回复
给你写一个例子,你可以自己试一下
        private static HttpListener listener;

       public static void demo()
        {
            if (listener == null)
            {
                listener = new HttpListener();
                var url = "http://+:9876/";
                listener.Prefixes.Add(url);
                listener.Start();
                listener.BeginGetContext(MainProcess, null);
            };
        }

        private static void MainProcess(IAsyncResult ar)
        {
            var context = listener.EndGetContext(ar);
            listener.BeginGetContext(MainProcess, null);
            var response = context.Response;
            response.AddHeader("Server", "My Server V0.0.1");
            var request = context.Request;
            var path = request.Url.LocalPath;
            if (path.StartsWith("/") || path.StartsWith("\\"))
                path = path.Substring(1);
            var sb = new StringBuilder("输入请求:");
            sb.AppendLine(path);
            var visit = path.Split(new char[] { '/', '\\' }, 2);
            if (visit.Length > 0)
            {
                var cmd = visit[0].ToLower();
                sb.AppendLine(string.Format("执行命令:{0}", cmd));
                sb.AppendLine(string.Format("另外有{0}个参数", visit.Length - 1 + request.QueryString.Count));
            }
            sb.AppendLine(DateTime.Now.ToString());
            response.ContentType = "text/plain;charset=UTF-8";
            var result = Encoding.UTF8.GetBytes(sb.ToString());
            using (var stream = response.OutputStream)
            {
                stream.Write(result, 0, result.Length);
            }
        }
运行之后,可以在浏览器试试 http://localhost:9876/abcd/aa.jsp?p=88sd&d=ksdf 你可以自己任意编写自己的 url 解析方式,跨过了低级的 http 处理,实现你自己的高级的处理机制。 显然,你自己部署一个 console控制台、wpf、windows service 程序,都可以自带有web服务器功能的!
  • 打赏
  • 举报
回复
threenewbee 2014-12-31
另外还有个 Nancy - Lightweight Web Framework for .net 完全不基于asp.net,也不用iis就可以在你的程序中集成web服务器 http://nancyfx.org/
  • 打赏
  • 举报
回复
threenewbee 2014-12-31
用不着了,asp.net 4.5支持owin标准,可以直接在你的进程中托管整个asp.net项目 http://www.cnblogs.com/shanyou/p/3650705.html
  • 打赏
  • 举报
回复
至少会比 IIS 性能好。
  • 打赏
  • 举报
回复
发帖
.NET Framework

1.7w+

社区成员

.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
帖子事件
创建了帖子
2014-12-31 08:32
社区公告
暂无公告