博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SignalR---服务端
阅读量:4504 次
发布时间:2019-06-08

本文共 9684 字,大约阅读时间需要 32 分钟。

前段时间把SignalR的官网教程大致看了一下,算是翻译了一遍,加上了自己的个人理解,

一下上传三个文件,分别是服务端、web客户端、DOTNET客户端相关文档,供大家参考。

其中有一处由于翻译时不专心,但又没能找到的错误,是说$.connetion.myHub和$.hubConnection其中是同一个对象的。

下面以代码形式上传,篇幅过长,有翻译不当的地方请浏览指出。

在Startup类中的Configuration方法里注册hub集线器。任何连接或集线器连接和配置都在这里注册。app.MapSignalr();注册所有的集线器。配置signalr代理的目录自动生成的js集线器代理默认生成在路径为web项目根目录/signalr/hubs。是可以通过代码改变这个默认路径的。在服务端appMapSignalR("/signalr",new HubConfiguration());其中signalr为新的路径。在JavaScript客户端(生成代理)$.connection.hub.url="/signalr";$.connection.hub.start().done(init);在JavaScript客户端(不生成代理)var connection=$.connection("/signalr",{userDefaultPath:false});在.NET客户端var hubConnection=new HubConnection("http://contoso.com/signalr",useDefaulrUrl:false);创建hub服务器public class MyHub:Hub 要继承Hub这个父类才能成为集线器。在JavaScript客户端使用生成的代理var connectionProxy=$.connection.myHub;其中muHub为服务器创建的Hub。在服务端可以改变Hub的名字,[HubName(proxyHub)]。定义强类型的Hubs通过定义一个接口interface让你的客户端调用,从Hub
派生。public class StrongHub:Hub
{public void Send(string message){Clients.All.MewMessage(message);}public interface IClinet{void NewMessage(string message);}}如何在服务端定义一个方法让客户端调用只要在Hub类里把方法定义成public公共的方法就行了。Js客户端调用服务端的方法时是驼峰命名法(首字母小写)服务端的方法public void NewContosoChatMessage(string userName, string message);客户端调用时contosoChatHubProxy.server.newContosoChatMessage(userName, message);首字母小写是可以调到的。如果想要一个具体的名字(原样输出),则使用到HubName这个属性。这样就可以原样调用。服务端[HubMethodName("PascalCaseNewContosoChatMessage")]public void NewContosoChatMessage(string userName, string message)客户端contosoChatHubProxy.server.PascalCaseNewContosoChatMessage(userName, message);在服务端也可以使用异步方法服务端public async Task
> GetAllStocks(){ // Returns data from a web service. var uri = Util.getServiceUri("Stocks"); using (HttpClient httpClient = new HttpClient()) { var response = await httpClient.GetAsync(uri); return (await response.Content.ReadAsAsync
>()); }}客户端stockTickerHubProxy.server.getAllStocks().done(function (stocks) { $.each(stocks, function () { alert(this.Symbol + ' ' + this.Price); });});Hub集线器提供了一个进程参数,通过IProgress
来定义public class ProgressHub : Hub{ public async Task
DoLongRunningThing(IProgress
progress) { for (int i = 0; i <= 100; i+=5) { await Task.Delay(200); progress.Report(i); } return "Job complete!"; }}服务端调用客户端的方法使用Clients这个属性去调用客户端的方法(这个方法必须是在连接了服务器的克短短里)。服务端public class ContosoChatHub : Hub{ public void NewContosoChatMessage(string name, string message) { Clients.All.addNewMessageToPage(name, message); }}客户端contosoChatHubProxy.client.addNewMessageToPage = function (name, message) { // Add the message to the page. $('#discussion').append('
  • ' + htmlEncode(name) + ': ' + htmlEncode(message) + '
  • ');};不能从客服端方法里得到返回值。int x = Clients.All.add(1,1);这样的代码就不起作用。客户端可以定义复杂的参数类型服务端public void SendMessage(string name, string message){ Clients.All.addContosoChatMessageToPage(new ContosoChatMessage() { UserName = name, Message = message });}客户端var contosoChatHubProxy = $.connection.contosoChatHub;contosoChatHubProxy.client.addMessageToPage = function (message) { console.log(message.UserName + ' ' + message.Message);});Clients返回的是HubConnectionContext集线器连接上下文对象。可以通过这个对象的属性选择那些客户端接收PRC。Clients.All.addContosoChatMessageToPage(name, message);全部连接的客户端Clients.Caller.addContosoChatMessageToPage(name, message);调用者Clients.Others.addContosoChatMessageToPage(name, message);全部的连接者,出来调用者Clients.Client(Context.ConnectionId).addContosoChatMessageToPage(name, message);特定的ConnectionIdClients.AllExcept(connectionId1, connectionId2).addContosoChatMessageToPage(name, message);//全部的连接者,除了特定的connectionIdClients.Group(groupName).addContosoChatMessageToPage(name, message);在一个特定的组里的全部连接者Clients.Group(groupName, connectionId1, connectionId2).addContosoChatMessageToPage(name, message);在一个特定组里的全部连接者,除了特定从conectionIdClients.OthersInGroup(groupName).addContosoChatMessageToPage(name, message);在一个组里的全部连接者,除了调用者Clients.User(userid).addContosoChatMessageToPage(name, message);一个特定的用户,用userId标识Clients.Clients(ConnectionIds).broadcastMessage(name, message);在一个列表里的所有客户端和群组,ConnectioIds是一个列表Clients.Groups(GroupIds).broadcastMessage(name, message);一个组列表Clients.Client(username).broadcastMessage(name, message);特定的用户名方法名称的匹配不区分大小写Clients.All.addContosoChatMessageToPage在服务器上将会执行AddContosoChatMessageToPage,addcontosochatmessagetopage或addContosoChatMessageToPage在客户端上。使用字符串变量当作方法名public void NewContosoChatMessage(string name, string message){ string methodToCall = "addContosoChatMessageToPage"; IClientProxy proxy = Clients.All; proxy.Invoke(methodToCall, name, message);}methodToCall为字符串,定义一个IClientPeoxy类,定义接受者。通过IClientProxy的Invoke方法来实现字符串方法,其中methodToCall为方法名,name和message为参数。在hub集线器如何管理组成员SignalR的群组(Groups)提供了广播消息的方法对所有的组成员。一个组可以有任意数量的成员,一个成员也可以在很多的组里。可以添加和删除组成员。服务端public class ContosoChatHub : Hub{ public Task JoinGroup(string groupName) { return Groups.Add(Context.ConnectionId, groupName); } public Task LeaveGroup(string groupName) { return Groups.Remove(Context.ConnectionId, groupName); }}Js客户端contosoChatHubProxy.server.joinGroup(groupName);contosoChatHubProxy.server.leaveGroup(groupName);组会自动创建,也会最后一个成员退出后自动消失。添加一个客户端到群组并发送消息public async Task JoinGroup(string groupName){ await Groups.Add(Context.ConnectionId, groupName); Clients.Group(groupname).addContosoChatMessageToPage(Context.ConnectionId + " added to group");}组成员持久化Signalr是持久的,用户不是。在Hub集线器如何管理连接的生命周期可以重写OnConnected、OnDisconnected、OnReconnected集线器的虚方法跟踪用户的连接和断开。跟踪用户名和连接ID之间的关联,这样就当客户端连接或断开时就可以运行自己的代码。public class ContosoChatHub : Hub{ public override Task OnConnected() { // Add your own code here. // For example: in a chat application, record the association between // the current connection ID and user name, and mark the user as online. // After the code in this method completes, the client is informed that // the connection is established; for example, in a JavaScript client, // the start().done callback is executed. return base.OnConnected(); } public override Task OnDisconnected() { // Add your own code here. // For example: in a chat application, mark the user as offline, // delete the association between the current connection id and user name. return base.OnDisconnected(); } public override Task OnReconnected() { // Add your own code here. // For example: in a chat application, you might have marked the // user as offline after a period of inactivity; in that case // mark the user as online again. return base.OnReconnected(); }}调用OnConnected、OnDisconnected和OnReconnected方法每次浏览器导航到新页面时,都必须建立一个新连接,这意味着SignalR将执行该OnDisconneted方法和OnConnected方法。当建立新的连接时,SignalR总是创建一个新的连接ID。OnReconnected 当连接时候没有超时,重新连接时会别调用。OnDisconnected 当客户端断开连接并且SignalR无法自动重新连接时,例如浏览器刷新到新页面。对一个客户端,它们的调用顺序是OnConnected、OnReconnected、OnDisconnected或者OnConnected、OnDisconnected。而不可能是OnConnected、OnDisconnected、OnResconnected。某些情况下,OnDisconnected不会被调用,例如服务端关闭、AppDomain被回收。一台服务器上线或AppDomain回收,某些客户端将触发OnReconnected事件。如何从Context属性获取有关客户端的消息Context属性是一个HubCallerContext类型的对象,通过这个对象可以获取调用者的信息。string connectionID = Context.ConnectionId;调用者的connectIdconnectionID是一个GUID由SignalR生成,不能有自己生成。每个连接都有一个connectionID,如果应用程序有多个hub集线器,则所有Hub都使用相同的connectionID。System.Collections.Specialized.NameValueCollection headers = Context.Request.Headers;HTTP标头数据System.Collections.Specialized.NameValueCollection queryString = Context.Request.QueryString;System.Collections.Specialized.NameValueCollection queryString = Context.Request.QueryString;string parameterValue = queryString["parametername"];查询字符串数据可以在客户端定义查询字符串,这也是传递数据的一种方式$.connection.hub.qs = { "version" : "1.0" };string transportMethod = queryString["transport"];连接传输方法值为transportMethod“webSockets”,“serverSentEvents”,“foreverFrame”或“longPolling”。System.Collections.Generic.IDictionary
    cookies = Context.Request.Cookies; Cookie也可以从Context.RequestCookies得到。System.Security.Principal.IPrincipal user = Context.User;用户信息System.Web.HttpContextBase httpContext = Context.Request.GetHttpContext();请求的HttpContext对象。也可以是HttpContext.Current。如何传递在客户端和hub类中传递数据客户端代理提供了一个state对象用于存储想要传输的数据。在服务端可以通过Client.Caller属性获取到这些数据。Client.Caller属性在两个方向都有效,也可以更新服务端的值传回到客户端。用方法名携带数据js客户端contosoChatHubProxy.state.userName = "Fadi Fakhouri";contosoChatHubProxy.state.computerName = "fadivm1";.NET客户端contosoChatHubProxy["userName"] = "Fadi Fakhouri";chatHubProxy["computerName"] = "fadivm1";服务端public void NewContosoChatMessage(string data){ string userName = Clients.Caller.userName; string computerName = Clients.Caller.computerName; Clients.Others.addContosoChatMessageToPage(message, userName, computerName);}在强类型hub集线器中,通过Client.CallerState访问这些数据。public void NewContosoChatMessage(string data){ string userName = Clients.CallerState.userName; string computerName = Clients.CallerState.computerName; Clients.Others.addContosoChatMessageToPage(data, userName, computerName);}记录集线器的错误public class ErrorHandlingPipelineModule : HubPipelineModule{ protected override void OnIncomingError(ExceptionContext exceptionContext, IHubIncomingInvokerContext invokerContext) { Debug.WriteLine("=> Exception " + exceptionContext.Error.Message); if (exceptionContext.Error.InnerException != null) { Debug.WriteLine("=> Inner Exception " + exceptionContext.Error.InnerException.Message); } base.OnIncomingError(exceptionContext, invokerContext); }}该类继承自HubPipelineModule,应为把错误抛给客户端是不安全的,所以定义个类用户处理这些错误。这个类重写了OnIncomingError方法来实现错误的处理。把这个类注册到异常处理模型中public void Configuration(IAppBuilder app){ // Any connection or hub wire up and configuration should go here GlobalHost.HubPipeline.AddModule(new ErrorHandlingPipelineModule()); app.MapSignalR();}在SignalR中,使用HubException类来。可以从任何中枢抛出错误。显示HtbException类的服务器代码public class MyHub : Hub{ public void Send(string message) { if(message.Contains("
  •   

    转载于:https://www.cnblogs.com/xiaoai123/p/6659954.html

    你可能感兴趣的文章
    FactoryMethod模式——设计模式学习
    查看>>
    Android中 AsyncTask
    查看>>
    原码、反码、补码和移码
    查看>>
    SQL存储过程与函数的区别
    查看>>
    vue项目配置使用flow类型检查
    查看>>
    @Resource和@Autowired区别
    查看>>
    VS2010打开就自动关闭问题解决
    查看>>
    python webdriver 测试框架-数据驱动txt文件驱动,带报告的例子
    查看>>
    动态代理相对于静态代理的优势
    查看>>
    持续部署之jenkins与gitlab(三)
    查看>>
    第二章 Jenkins安装与配置
    查看>>
    POJ 3169 Layout 差分约束系统
    查看>>
    用动画切换按钮的状态
    查看>>
    JNI简易教程,windows and linux
    查看>>
    SVN下如何切换默认用户
    查看>>
    一个小时搭建一个全栈 Web 应用框架(下)——美化与功能
    查看>>
    第七周进度条博客
    查看>>
    2017年6月9日10:12:40 了解自己才能掌控自己 与 深度学习
    查看>>
    Android 手机的屏幕分辨率大小汇总
    查看>>
    PhpStorm修改字体
    查看>>