3

你们中有人尝试过将 PushStreamContent 与 WebApi 一起使用吗?我注意到奇怪的行为。这是我的代码(我知道的糟糕的代码 - 只是测试)

public class MsgModel
    {
        public MsgModel()
        {
            this.date = DateTime.Now.ToShortTimeString();
        }
        public string msg { get; set; }
        public string date { get; set; }
    }
    [RoutePrefix("rx")]
    public class RxController : ApiController
    {
        private static ConcurrentDictionary< string, Stream> clients = new ConcurrentDictionary< string, Stream>();

        [HttpGet]
        [Route("subscribe")]
        public async Task<HttpResponseMessage> Subscribe(HttpRequestMessage request)
        {
            var response = request.CreateResponse();
            response.Content = new PushStreamContent(async (a, b, c) => { await OnStreamAvailable(a, b, c); }, "text/event-stream");

            return response;
        }

        private static  void WriteEventToStreamAsync(Guid id , string type , string data , Stream stream )
        {
            try
            {
                StreamWriter sw = new StreamWriter(stream);

                sw.Write("event: " + type + "\n");
                sw.Write("id: " + Guid.NewGuid() + "\n");
                sw.Write("data: " + data + "\n\n");
                sw.Flush();
                stream.Flush();
            }
            catch(Exception e)
            {
                StreamWriter ignore;
                //clients.TryRemove( out ignore);
            }
        }



        [HttpPost]
        [Route("msg")]
        public IHttpActionResult Push(MsgModel model)
        {

            foreach (var clientPair in clients)
            {
                var client = clientPair.Value;
                try
                {

                    WriteEventToStreamAsync(Guid.NewGuid(), "push", JsonConvert.SerializeObject(model), client);
                }
                catch (Exception)
                {
                    Stream ignore;
                    clients.TryRemove(clientPair.Key ,out  ignore);
                }
            }
            return Ok();
        }




        private async Task OnStreamAvailable(Stream stream, HttpContent content, TransportContext context)
        {


            WriteEventToStreamAsync(Guid.NewGuid(), "welcome", JsonConvert.SerializeObject(new MsgModel() { msg = "Welcome" }), stream);
            var userName = this.User.Identity.Name;
            Stream ignore;
            clients.TryRemove(userName,out  ignore);
            clients.TryAdd(this.User.Identity.Name  , stream);
        }
    } 

现在......似乎一切正常,但事实上,当我尝试在前端使用它时,我大部分时间都会收到一条落后于当前状态的消息。所以起初我有空流(在前端),然后在调用“推送”方法后我得到“欢迎”消息等等。当我使用异步方法时,行为保持不变。此外,它不是确定性的。有时我会收到所有消息,有时会收到一条消息。

请。不要因为这个问题杀了我;)我可能会遗漏一些东西。

4

1 回答 1

2

我不太明白为什么,但它在发送时对我有用\r\n\r\n(即使规范说\n\n)。出于某种原因,我只有 IIS 有这个问题,因为我不需要在 IIS Express 或 OWIN 自主机中使用这种解决方法。

sw.Write("data: " + data + "\r\n\r\n");
sw.Flush();
于 2019-12-19T18:03:12.877 回答