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

服务端


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

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

  1. public class ChatHub : Hub
  2. {
  3. public void Send(string name, string message)
  4. {
  5. Console.WriteLine("ConnectionId:{0}, InvokeMethod:{1}", Context.ConnectionId, "Send");
  6. Clients.AllExcept(Context.ConnectionId).broadcast(name, message);
  7. }
  8. }

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

  1. [assembly: OwinStartup(typeof(Host.Startup))]
  2.  
  3. namespace Host
  4. {
  5. public class Startup
  6. {
  7. public void Configuration(IAppBuilder app)
  8. {
  9. app.MapSignalR();
  10. }
  11. }
  12. }

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

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. var url = "localhost:10086";
  6. WebApp.Start<Startup>(url);
  7. Console.WriteLine("Server started,url is {0}", url);
  8. Console.ReadLine();
  9. }
  10. }

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

控制台启动后的输出。

用浏览器访问

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

客户端


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

  1. var url = "http://localhost:10086/";
  2. var connection = new HubConnection(url);
  3. var chatHub = connection.CreateHubProxy("ChatHub");
  4. connection.Start().ContinueWith(t =>
  5. {
  6. if (t.IsFaulted)
  7. {
  8. Console.WriteLine("Connection fault.");
  9. }
  10. });

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

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

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

  1. Console.WriteLine("Please input your name:");
  2. var _name = Console.ReadLine();
  3. Console.WriteLine("Start chat!");
  4. while (true)
  5. {
  6. var _message = Console.ReadLine();
  7. chatHub.Invoke("Send", _name, _message).ContinueWith(t => {
  8. if (t.IsFaulted)
  9. {
  10. Console.WriteLine("Connection error!");
  11. }
  12. });
  13. }

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

执行效果


执行效果如图。

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

问题


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

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

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

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

SignalR循序渐进(一)简单的聊天程序的更多相关文章

  1. Socket编程实践(3) 多连接服务器实现与简单P2P聊天程序例程

    SO_REUSEADDR选项 在上一篇文章的最后我们贴出了一个简单的C/S通信的例程.在该例程序中,使用"Ctrl+c"结束通信后,服务器是无法立即重启的,如果尝试重启服务器,将被 ...

  2. C#编写简单的聊天程序

    这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考.文章大体分为四个部分:程序的分析与设计.C#网络编 ...

  3. 简单的聊天程序,主要用到的是Socket

    服务端: import java.io.*; import java.net.*; import java.util.*; public class ChatServer { boolean stat ...

  4. Udp实现简单的聊天程序

    在<UDP通讯协议>这篇文章中,简单的说明了Udp协议特征及如何Udp协议传输数据 这里将用Udp协议技术,编写一个简单的聊天程序: //发送端: package com.shindo.j ...

  5. 使用Ajax long polling实现简单的聊天程序

    关于web实时通信,通常使用长轮询或这长连接方式进行实现. 为了能够实际体会长轮询,通过Ajax长轮询实现了一个简单的聊天程序,在此作为笔记. 长轮询 传统的轮询方式是,客户端定时(一般使用setIn ...

  6. C#编写简单的聊天程序(转)

    这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考.文章大体分为四个部分:程序的分析与设计.C#网络编 ...

  7. Java网络编程以及简单的聊天程序

    网络编程技术是互联网技术中的主流编程技术之一,懂的一些基本的操作是非常必要的.这章主要讲解网络编程,UDP和Socket编程,以及使用Socket做一个简单的聊天软件. 全部代码下载:链接 1.网络编 ...

  8. socket实例C语言:一个简单的聊天程序

    我们老师让写一个简单的聊天软件,并且实现不同机子之间的通信,我用的是SOCKET编程.不废话多说了,先附上代码: 服务器端server.c #include <stdio.h> #incl ...

  9. UDP—Socket,套接字聊天简单的聊天程序。

    思路:(发送端) 1.既然需要聊天.就应该怎么建立聊天程序,,DatagramSocket对象http://www.w3cschool.cc/manual/jdk1.6/ DatagramSocket ...

随机推荐

  1. Delphi记录record中的变体

    program Day4; {$APPTYPE CONSOLE} uses SysUtils, Util in 'Util.pas'; type TPerson = packed record ID ...

  2. vue 的调试工具

    转载自:http://www.cnblogs.com/lolDragon/p/6268345.html 安装 1.github下载地址:https://github.com/vuejs/vue-dev ...

  3. SAP ECC6安装系列四:安装过程详解

    原作者博客 http://www.cnblogs.com/Michael_z/ ======================================== 续接上篇,我们终于按下了 “Next” ...

  4. Java中的阻塞队列(BlockingQueue)

    1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...

  5. notification 报错the method build() is undefined for the type Notificatin.Builder

    notification 报错the method build() is undefined for the type Notificatin.Builder 这事api版本号太低导致的 Notifi ...

  6. 对于try catch放在能够很好地处理例外的位置

    Exception有一个message属性.在使用catch的时候可以调用: Catch(IOException e){System.out.println(e.message())}; Catch( ...

  7. ti8168平台的tiler memory

    DM8168 DMM/TILER简介 1.概述 如图4-1,DMM定位在SDRAM控制器的前端,是所有initiator产生的内存存取的接口. 动态内存管理器DMM,是一个专门的管理模块,广义上说,包 ...

  8. 测试RESTful API利器-Postman

    对于前端开发者而言,最需要的往往不是技术本身,其实技术都没什么难的,而最缺少的则是各种各样好的兵器,比如调试,开发工具等等. 我们这里就推荐一款前端开发的利器-Postman,它是Google Chr ...

  9. jquery ajax生成Select

    function DropDownList(url, domId, defaultValue) {    /// <summary>    /// ajax生成select    /// ...

  10. Excel 经常使用的公式总结

    INDIRECT 返回并显示指定引用的内容.使用INDIRECT函数可引用其他工作簿的名称.工作表名称和单元格引用.   indirect函数对单元格引用的两种 A B C D INDIRECT(&q ...