ServiceStack JavaScript服务器事件客户端

时间:2016-05-10 08:11:06

标签: javascript servicestack

我正在尝试使用ServerEvents设置servicestack。 我已经为ServerEventsFeature添加了插件。 我正在使用Javascript server events client,我尝试了一个简单的示例,在用户通过身份验证后在客户端上执行此操作

  var source = new EventSource('http://localhost/ecmapi/event-stream?channel=MyChannel');
  $(source).handleServerEvents({
           handlers: {
                  onConnect: function (subscription) {
                       console.log("connected! welcome " + subscription.displayName);
                  }, 
                  onHeartbeat: function (msg, e) {
                      //console.log("onHeartbeat", msg, e);
                       },
                  showNotification: function (type, e) {
                        console.log("showNotification", type);
                        } 
                  }
           });

在apphost文件中:

            Plugins.Add(new ServerEventsFeature
                   {
                       StreamPath = "/event-stream",           
                       HeartbeatPath = "/event-heartbeat",     
                       UnRegisterPath = "/event-unregister",    
                       SubscribersPath = null, 
                       LimitToAuthenticatedUsers = false, 
                       NotifyChannelOfSubscriptions = false
                   });

要向客户发送一个事件,我正在呼叫:

ServerEvents.NotifyChannel("MyChannel", "cmd.showNotification", message);

我在客户端的showNotification函数上成功收到它。

但是,subscription.displayName是自动生成的,与当前登录的用户无关。此外,如果我将LimitToAuthenticatedUsers设置为true,则会重新启动401错误。

我的问题是,还需要什么,以便javascript服务器事件客户端可以与已登录的用户一起工作?我想要使​​用ServerEvents.NotifyUserName或ServerEvents.NotifyUserId函数,并且只允许经过身份验证的用户订阅。

谢谢!

**请求的auth和EventSource的请求和响应标头**

请求身份验证

POST http://localhost/ECMAPI/auth.json HTTP / 1.1 接受: / Content-Type:application / json X-Requested-With:XMLHttpRequest 推荐人:http://localhost/InterfaceGov/Default.aspx 接受语言:en-gb Accept-Encoding:gzip,deflate 用户代理:Mozilla / 5.0(兼容; MSIE 9.0; Windows NT 6.1; WOW64; Trident / 5.0) 主持人:localhost 内容长度:43 连接:保持活力 Pragma:没有缓存 Cookie:_ga = GA1.1.2077781525.1452005918; .ASPXANONYMOUS = hOL_MQPsZk5z5t31805S8oazFP0IdbeHKBejAH2x2Ic6hS5070aWW5A-2dklH10qT8IE9pshiAgUkmwN-TfVXjXUhAYVaWKzuOIyCy1nE8VAdETQk1TqB_39gk5ST8cIcvO2KNgB8d5h1f38W8hIzg2; SS-PID = hMBothYg2ETWObMTMJDY; SS-ID = x9zxOTH2rFxLo8tO01Nw

响应身份验证

HTTP / 1.1 200好的 缓存控制:私有 Content-Type:application / json;字符集= utf-8的 变化:接受 服务器:Microsoft-IIS / 7.5 X-Powered-By:ServiceStack / 4.038 Win32NT / .NET Access-Control-Allow-Origin:* 访问控制允许方法:GET,POST,PUT,DELETE,OPTIONS Access-Control-Allow-Headers:内容类型,授权 X-AspNet-Version:4.0.30319 Set-Cookie:ss-pid = QjEKGQphtPJZjZJmPtCt; expires = Sun,11-May-2036 12:18:29 GMT;路径= /;仅Http Set-Cookie:ss-id = 1yKLtkiTD2NshpiPrffu;路径= /;仅Http X-MiniProfiler-Ids:[" 1d0459ec1fad4695ac0f3c7fc69cad0a"," 3f5cd3515e084363b86df1e54633a683"," 0f54d87508594cba9757660dc664aeef"] X-Powered-By:ASP.NET 日期:2016年5月11日星期三格林尼治标准时间12:18:30 内容长度:17514

请求EventSource

获取http://localhost/ecmapi/event-stream?channel=MyChannel HTTP / 1.1 接受: / 来源:http://localhost Accept-Language:en-GB Accept-Encoding:gzip,deflate 用户代理:Mozilla / 5.0(兼容; MSIE 9.0; Windows NT 6.1; WOW64; Trident / 5.0) 主持人:localhost 连接:保持活力 Pragma:no-cache

响应事件源

HTTP / 1.1 401未经授权 缓存控制:私有 变化:接受 服务器:Microsoft-IIS / 7.5 WWW-Authenticate:凭证realm =" / auth / credentials" X-Powered-By:ServiceStack / 4.038 Win32NT / .NET Access-Control-Allow-Origin:* 访问控制允许方法:GET,POST,PUT,DELETE,OPTIONS Access-Control-Allow-Headers:内容类型,授权 X-AspNet-Version:4.0.30319 Set-Cookie:ss-pid = c0UQXy4YJNQmVuUiEVfA; expires = Sun,11-May-2036 12:18:30 GMT;路径= /;仅Http Set-Cookie:ss-id = y9e8BbD1na5EoHu8GUug;路径= /;仅Http X-MiniProfiler-Ids:[" 1d0459ec1fad4695ac0f3c7fc69cad0a"," 3f5cd3515e084363b86df1e54633a683"," 0f54d87508594cba9757660dc664aeef"," f1584abd58e64a9dac6ceceaa932c47a"] X-Powered-By:ASP.NET 日期:2016年5月11日星期三格林尼治标准时间12:18:30 内容长度:0

1 个答案:

答案 0 :(得分:2)

/event-stream返回 401 Unauthorized 的原因是您对/event-stream的请求不包含必要的会话Cookie,这是建立Authenticated请求的内容。

这只是IE中的一个问题,因为它是剩下的最后一个没有native support for Server Sent Events的浏览器,并且需要SSE垫片才能工作,其中一个限制是它不会发送会话Cookie。

default_ieshim.cshtml直播演示中的http://chat.servicestack.net/default_ieshim显示了如何在IE中支持经过身份验证的请求,而是将ss-id sessionId附加到您可以在Razor中填充的事件流网址中页面:

var source = new EventSource(
  '/event-stream?channels=@channels&ss-id=@(base.GetSession().Id)&t=' 
  + new Date().getTime());

您还需要告诉ServiceStack接受Url中的会话ID,您可以在AppHost Configure()中执行以下操作:

SetConfig(new HostConfig {
    AllowSessionIdsInHttpParams = true,
});