首页 新闻 会员 周边

asp.net webapi 使用 EventSource 推送消息问题

0
悬赏园豆:30 [已关闭问题] 关闭于 2016-10-20 17:29

最近在做的一个项目,是一个web项目,需要从服务端主动推送数据到客户端,其实有很多实现方式,但是选择了一种实现起来相对简单的就是使用 EventSource 来实现,实现起来也很简单,参考了网络上的一些实现方法。实现以后测试发现一些问题,采用IISExpress 作为服务器,客户端能接受到服务端推送的消息,并且刷新客户端以后,还能继续接收,但是如果换成IIS服务器,则第一次能够访问,刷新以后,客户端状态一直出来pending状态,查看记得的日志,在IIS服务器中,如果是刷新请求的话,服务器报错:远程主机关闭连接,错误代码:0x800704cd。

下面是我的服务端实现代码,麻烦各位园友帮忙看看。感谢感谢。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Web.Http;
using Harrenhal.Merchant.Utility;
using StackExchange.Redis;
using StackExchange.Redis.Extensions.Core;
using StackExchange.Redis.Extensions.Newtonsoft;
using Sylvanas.Logging;
using Sylvanas.Logging.Extensions;

namespace Harrenhal.Merchant.Controllers
{
    [RoutePrefix("api/event")]
    public class EventController : ApiController
    {
        private static readonly ILogger Logger = LoggerCache.GetLogger(typeof(EventController));
        private static readonly string DispatchSuccessEventPrefix = "DispatchSuccess";
        private static Timer _timer = default(Timer);

        private static readonly ConcurrentDictionary<string, StreamWriter> StreamWriters =
            new ConcurrentDictionary<string, StreamWriter>();

        public EventController()
        {
            _timer = _timer ?? new Timer(TimerCallback, null, 0, 1000);
        }

        public HttpResponseMessage Get(string userid)
        {
            var response = Request.CreateResponse();
            response.Content =
                new PushStreamContent(
                    (stream, httpContent, transportContext) =>
                    {
                        var writer = new StreamWriter(stream);
                        StreamWriters.TryAdd(userid, writer);
                    }, "text/event-stream");

            return response;
        }

        private static void TimerCallback(object state)
        {
            _timer.Change(Timeout.Infinite, Timeout.Infinite);
            try
            {
                foreach (var streamWriter in StreamWriters)
                {
                    //ConnectionMultiplexer connectionMultiplexer =
                    //    RedisUtility.GetConnection(
                    //        ConfigurationManager.ConnectionStrings["My.Redis.Cache"].ConnectionString);

                    //var client = new StackExchangeRedisCacheClient(connectionMultiplexer,
                    //    new NewtonsoftSerializer());
                    //var key =
                    //    client.SearchKeys($"{GetLocalizedKey(DispatchSuccessEventPrefix, streamWriter.Key)}*")
                    //        .FirstOrDefault();

                    //var writer = streamWriter.Value;
                    //if (key != null)
                    //{
                    //    Logger.Error($"key:{key}");
                    //    var database = connectionMultiplexer.GetDatabase();
                    //    var message = database.StringGet(key);
                    //    Logger.Error($"message:{message}");

                    //    if (!message.IsNullOrEmpty)
                    //    {
                    //        database.KeyDelete(key);

                    //        writer.WriteLine("data:" + message + "\n");
                    //    }
                    //    else
                    //    {
                    //        writer.WriteLine("data:" + "\n");
                    //    }
                    //}
                    //else
                    //{
                    //    writer.WriteLine("data:" + "\n");
                    //}
                    //writer.Flush();
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "获取通知消息失败");
            }
            finally
            {
                _timer.Change(1000, 1000);
            }
        }

        private static string GetLocalizedKey(string prefix, string key)
        {
            return prefix + ":Cache:" + key;
            
        }
    }
}

 

Arthur1024的主页 Arthur1024 | 初学一级 | 园豆:91
提问于:2016-10-17 23:37
< >
分享
所有回答(1)
0

你刷新了,之前的服务端对你客户端发送响应的就断了,当然会报那个错。

webapi没怎么用过,你看下Response中还有没有一个IsClientConnected的属性,用于判断客户端是否还连着在。

Daniel Cai | 园豆:10424 (专家六级) | 2016-10-18 10:52

但是在IISExpress 中就不会出现这种情况,可以刷新

支持(0) 反对(0) Arthur1024 | 园豆:91 (初学一级) | 2016-10-18 15:34
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册