标签:default mic 请求 localhost type 属性 产生 sign cross
SignalR 有三块,
Server:
Hub Server
Custom Message Sender Service (Sender Proxy)
Client:
Message Sender
Message Receiver
1. Hub Server & Sender Proxy Service
Hub Server 和 Custom Message Sender Service 在一个app中,“Custom Message Sender Service” 通过api直接控制Hub Server行为。(connection filtering, status, deliver message, etc )
2. 跨域
Sender, Receiver 和 Hub Server 可能都不在同一个域里。 会有跨域访问的问题。
3. 发消息的客户端,
可以有两种方式发消息给Hub Server
3.1 通过hubproxy.server.func(), 走的是signalR的persistent connection. (这种情形下一般只发一次消息,persistent connection占用了资源,浪费。 当然也可以建立完释放,persistent connection -> send message -> close persistent connection)。 这种模式下,跨域由SignalR Hub框架控制。
3.2 通过ajax调用 "Custom Message Sender Service (Proxy)", 由Proxy调用Hub的服务。 这种结构更干净,发送者和SignalR connection没有关系, 走单独Http请求。 跨域由 "Custom Message Sender Service (Proxy)", 一般由服务端暴露服务(MVC/WebAPI). 但是MVC和WebApi的跨域管理不太一样。(见“MVC和WebApi的跨域管理”)
3.3 有一种情况可以考虑用signalR的persistent connection发消息。 就是发消息的人,同时又是收消息的人。 那么一个persistent connection可以同时用来收发消息。
4. 收消息的客户端
这个只有一种,“持久连接,保持监听”。
4.1 SignalR保持连接的方式由协议本身定义,由服务器和浏览器支持。 WebSocket / iFrame / longPooling。 具体可google
4.2 WebSocket的效率要比其他高很多,比较reliable,比如disconnect, 其他方式可能不能直接反应客户端关闭的动作,需要等待超时发生触发disconnect. 代码和排错上有时比较费解。
4.3 【Hub Server服务端】微软的WebApp PaaS上, by default, "WebSocket"不enable。要去管理界面把它打开。
5. Hub Server
5.1 Owin中map /signalr 作为SignalR routing的开始
(https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server#tracing If you are adding SignalR functionality to an ASP.NET MVC application, make sure that the SignalR route is added before the other routes. For more information, see Tutorial: Getting Started with SignalR 2 and MVC 5.)
5.2 跨域访问由Owin框架自己处理, 如果再由IIS web.config来控制CORS, 会产生冲突。
5.3 Hub Server中的方法,只是个签名,具体实现不重要(无需写实现,除非客户端用hub.server.func()发消息)。 主要作用
5.3.1 生成客户端代理类。
5.3.2 让代理类绑定本地方法,以被服务端调用
6. Sender Message Proxy
6.1 如果用MVC做,有个很大的问题就是,跨域。
6.1.1 如果浏览器是IE, 问题不是很大。 貌似preflight request 被省略了。 request 被直接提交到MVC层, 可以自定义Action属性, 加入”Access-Control-Allow-Origin“。
6.1.2 如果浏览器是Chrome, "preflight request"不会被忽略. http option verb会发过来。 这个时候MVC就有问题了, 无论从owin还是application_beginRequest,都无法获得这个request,无法修改http头,使得CORS通过。 (猜想是不是MVC的routing,所在的层次太高,获得不了这种request)
6.1.3 对于simple CORS, IE 和 Chrome (Chrome 无须preflight), 如果用Get/Post传数据,由于不走preflight, 自定义Action属性修改http header是可行的。 但是如果用ajax, 有content type header的话, 那就必须要走preflight.
7. IIS setting, web.config
实际使用当中,如果使用MVC 和 SignalR, 客户端用ajax post json (content type = application / json), 那么需要考虑直接使用直接从服务器设置应用CORS。 这个时候SignalR的CORS需要被取消(//map.UseCors(CorsOptions.AllowAll) )
<add name="Access-Control-Allow-Origin" value="https://localhost:44300" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Credentials" value="true" />
CORS 介绍
一篇很好的文章介绍CORS:https://staticapps.org/articles/cross-domain-requests-with-cors/
注意Simple CORS / Complex CORS 的区别
常用代码
var heartBeat = GlobalHost.DependencyResolver.Resolve<ITransportHeartbeat>();
var connectionAlive = heartBeat.GetConnections().FirstOrDefault(c=>c.ConnectionId == connection.ConnectionId);
if (connectionAlive.IsAlive)
{//Do whatever...}
======================================================
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
IHubContext context = GlobalHost.ConnectionManager.GetHubContext(“MyHub”);
======================================================
public class EnableCorsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
base.OnActionExecuting(filterContext);
}
}
标签:default mic 请求 localhost type 属性 产生 sign cross
原文地址:http://www.cnblogs.com/chsw/p/6830398.html