zoukankan      html  css  js  c++  java
  • SignalR1

    SignalR循序渐进(一)

    前阵子把玩了一下SignalR,起初以为只是个real-time的web通讯组件。研究了几天后发现,这玩意简直屌炸天,它完全就是个.net的双向异步通讯框架,用它能做很多不可思议的东西。它基于Owin,可以脱离繁重的System.Web,随意寄宿在IIS,WindowsService,或者一个控制台程序,这样它即能用于b/s的Web应用,也能用在客户端程序或者服务之间的通讯上。对它的介绍网上早已铺天盖地,这而就不再啰嗦了,先来个小例子,一个聊天室程序。

    服务端


    image

    新建一个叫SignalRDemo的工程,注意一定要选择.net Framework4.5及以上。

    image

    为了让服务端可以自寄宿,安装signalr self host组件。

    复制代码
    public class ChatHub : Hub
        {
            public void Send(string name, string message)
            {
                Console.WriteLine("ConnectionId:{0}, InvokeMethod:{1}", Context.ConnectionId, "Send");
                Clients.AllExcept(Context.ConnectionId).broadcast(name, message);
            }
        }
    复制代码

    新建一个ChatHub,创建一个行为叫Send,里面包含了一条控制台调用记录以及让所有除了发起者外的链接Hub的客户端执行客户端方法broadcast。

    复制代码
    [assembly: OwinStartup(typeof(Host.Startup))]
    
    namespace Host
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.MapSignalR();
            }
        }
    }
    复制代码

    创建一个启动类,将所有的Hub映射。

    复制代码
    class Program
        {
            static void Main(string[] args)
            {
                var url = "localhost:10086";
                WebApp.Start<Startup>(url);
                Console.WriteLine("Server started,url is {0}", url);
                Console.ReadLine();
            }
        }
    复制代码

    在Main中写上url和端口,直接用WebApp启动。

    image

    控制台启动后的输出。

    image

    用浏览器访问

    好了,到这儿服务端代码就全部完成了。接下来创建客户端来调用。客户端暂时不采用website,同样用控制台程序来承载。

    客户端


    image

    创建一个Client的控制台工程,添加SignalR的Client包。

    复制代码
    var url = "http://localhost:10086/";
                var connection = new HubConnection(url);
                var chatHub = connection.CreateHubProxy("ChatHub");
                connection.Start().ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        Console.WriteLine("Connection fault.");
                    }
                });
    复制代码

    在客户端的Main中创建一个HubConnection,创建ChatHub的代理,通过connection.Start启动连接。

    var broadcastHandler = chatHub.On<string, string>("broadcast", (name, message) =>
                {
                    Console.WriteLine("[{0}]{1}: {2}", DateTime.Now.ToString("HH:mm:ss"), name, message);
                });

    定义客户端方法,之前在服务端用Clients.All.broadcast的就是在这边定义的方法。

    复制代码
    Console.WriteLine("Please input your name:");
                var _name = Console.ReadLine();
                Console.WriteLine("Start chat!");
                while (true)
                {
                    var _message = Console.ReadLine();
                    chatHub.Invoke("Send", _name, _message).ContinueWith(t => {
                        if (t.IsFaulted)
                        {
                            Console.WriteLine("Connection error!");
                        }
                    });
                }
    复制代码

    最后,写上一个简单的聊天逻辑。当输入名字后,在while的循环内,每输入一行文本,hub就调用服务端的Send方法。同时服务端在执行Send的过程后又会回掉客户端方法。这种通讯方式在以前的C#代码中是很不可思议的,因为同样的客户端方法还可以写在js里!

     

    执行效果


    image

    执行效果如图。

    好了,一个基于SignalR的简单的控制台聊天程序就完成了,强大的SignalR让开发者不需要关心Socket的一堆烦人的问题。

     

    问题


    上面的那个聊天程序看似很方便很强大,但似乎哪儿有一些奇怪?

    比如说,服务端调用客户端的方法用的是dynamic的,客户端调用服务端的方法传入的都是string类型的,这样首先就不具备扩展性和进行一些规则约束。

    1. 能不能让客户端声明一个强类型的方法列表呢?这样首先不容易写错。
    2. 同样的,能不能让服务端声明一个强类型的方法列表给客户端调用呢?

    下一篇将对上面的2个问题进行思考,并给出解决方案。

     
     
     
    标签: SignalR
  • 相关阅读:
    Linux下对拍(A+B问题)
    洛谷 P1043 数字游戏 区间DP
    6.22 集训--DP复习一
    洛谷 P1220 关路灯 区间DP
    A*算法求K短路模板 POJ 2449
    点分治模板 POJ 1741
    HDU
    棋子游戏 51Nod
    数论习题总结
    CodeForces
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3734177.html
Copyright © 2011-2022 走看看