说明:开发的案例为Hub(集线器)

一、开发环境

  VS2013  ,window10

二、步骤

  打开vs创建一个新的解决方案,添加一个空的WebForm项目。

  使用NuGet添加引用。命令:PM>  instal-package Microsoft.AspNet.SignalR 或者 工具->NuGet程序包管理器->管理解决方案的NuGet程序包,里搜索和添加

三、添加Default.aspx页面

  页面中首先引用jquery 1.6.4 及以上版本库

  添加引用jquery.signalR-2.2.1.min.js 库

  添加script引用 /signalr/js

  以上为引用为必须,并且顺序不可调整, /signalr/js 依赖与jquery.signalR-2.2.1.min.js库,并且是动态生成的(即:不存在该文件)

  Default.aspx页面的html代码如下:

  

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Drawing board</title>
<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
<script src="/signalr/js"></script>
<script src="Scripts/DrawingBoard.js"></script>
<style>
div {
margin: 3px;
} canvas {
border: 2px solid #808080;
cursor: default;
}
</style>
</head>
<body>
<div>
<div>
<label for="color">Color: </label>
<select id="color">
</select>
</div>
<canvas id="canvas" width="300" height="300"></canvas>
<div>
<button id="clear">Clear canvas</button>
</div>
</div>
</body>
</html>

  页面实现功能描述:实现简单画板的多个页面同步功能。

  代码中 #canvas为画板所用标签  ,#color 为画笔颜色选项,#clear为清除画板的按钮

  Scripts/DrawingBoard.js  代码为Hub客户端必要的逻辑。代码如下:

  

$(function () {

    ///////////////////////////////////////////////////////////////
// Standard drawing board functionalities
/////////////////////////////////////////////////////////////// var colors = ["black", "red", "green", "blue", "yellow", "magenta", "white"];
var canvas = $("#canvas");
var colorElement = $("#color");
for (var i = 0; i < colors.length; i++) {
colorElement.append(
"<option value='" + (i + 1) + "'>" + colors[i] + "</li>"
);
}
var buttonPressed = false;
canvas
.mousedown(function () {
buttonPressed = true;
})
.mouseup(function () {
buttonPressed = false;
})
.mousemove(function (e) {
if (buttonPressed) {
setPoint(e.offsetX, e.offsetY, colorElement.val());
}
}); var ctx = canvas[0].getContext("2d");
function setPoint(x, y, color) {
ctx.fillStyle = colors[color-1];
ctx.beginPath();
ctx.arc(x, y, 2, 0, Math.PI * 2);
ctx.fill();
}
function clearPoints() {
ctx.clearRect(0, 0, canvas.width(), canvas.height());
} $("#clear").click(function () {
clearPoints();
}); ///////////////////////////////////////////////////////////////
// SignalR specific code
/////////////////////////////////////////////////////////////// var hub = $.connection.drawingBoard;
hub.state.color = colorElement.val(); // Accessible from server
var connected = false; // UI events
colorElement.change(function () {
hub.state.color = $(this).val();
});
canvas.mousemove(function (e) {
if (buttonPressed && connected) {
hub.server.broadcastPoint(
Math.round(e.offsetX), Math.round(e.offsetY)
);
}
});
$("#clear").click(function () {
if (connected) {
hub.server.broadcastClear();
}
}); // Event handlers
hub.client.clear = function () {
clearPoints();
};
hub.client.drawPoint = function (x, y, color) {
setPoint(x, y, color);
};
hub.client.update = function (points) {
if (!points) return;
for (var x = 0; x < 300; x++) {
for (var y = 0; y < 300; y++) {
if (points[x][y]) {
setPoint(x, y, points[x][y]);
}
}
}
}; // Voila!
$.connection.hub.start()
.done(function () {
connected = true;
}); });

  js中关于本文核心代码表述:

   var hub = $.connection.drawingBoard;  固定写法,创建集线器代理工具(此处只能意会)

   hub.state.color = colorElement.val(); //   画笔颜色参数,类似于url传递querystring 参数,可查看下文中C#代码理解

   var connected = false;  //状态标志

   hub.state.color = $(this).val(); //设置参数值,同上文

   hub.server.broadcastPoint(Math.round(e.offsetX), Math.round(e.offsetY));  //调用服务器端的服务方法  BroadcastPoint  ,在花瓣上打印一个点

  注解:服务端的方法在web端调取时候需要第一个字幕小写开头,详情请自行百度

   hub.server.broadcastClear();  //调用服务端清空画板服务方法

   hub.client.clear = function () {

    clearPoints();   //客户端清除
   };

   hub.client.drawPoint

   hub.client.update

    注解:以上两条请参考上文中解释

   $.connection.hub.start()    //开始建立链接

    .done(function () {  //暂忘记了
      connected = true;
    });

四、添加启动类

  根目录下添加  Startup.cs文件,代码如下:

  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Owin; namespace Test
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}

  注解: app.MapSignalR();用于注册默认服务

五、添加Hub服务

  根目录下添加DrawingBoard.cs  代码如下:

  

using System.Threading.Tasks;
using Microsoft.AspNet.SignalR; namespace DrawingBoard
{
public class DrawingBoard : Hub
{
private const int BoardWidth = , BoardHeight = ;
private static int[,] _buffer = GetEmptyBuffer();
public Task BroadcastPoint(int x, int y)
{
if (x < ) x = ;
if (x >= BoardWidth) x = BoardWidth - ;
if (y < ) y = ;
if (y >= BoardHeight) y = BoardHeight - ; int color = ;
int.TryParse(Clients.Caller.color, out color);
_buffer[x, y] = color;
return Clients.Others.DrawPoint(x, y, Clients.Caller.color);
}
public Task BroadcastClear()
{
_buffer = GetEmptyBuffer();
return Clients.Others.Clear();
} public override Task OnConnected()
{
return Clients.Caller.Update(_buffer);
} private static int[,] GetEmptyBuffer()
{
var buffer = new int[BoardWidth, BoardHeight];
return buffer;
}
}
}

  逻辑并不复杂,就是转发客户端传递进来的数据给其他客户端,请自行理解。

开发中遇到的问题:

  配置错误,开始时候使用web.config配置,发现报错了具体错误已经丢失,发现是 Startup  配置错误,Startup.cs可以立即为默认的必须的存在的。推测可以使用web.config配置为其他启动类,但是未测试。

  具体请关注后续文章。

运行效果图:

  

  

请注意:本文中代码摘自ASP.NET  SignalR 编程实践一书 豆瓣链接:https://book.douban.com/subject/26378222/

第一个SignalR案例的更多相关文章

  1. 第一个struts案例及分析

    软件中的框架,是一种半成品: 我们项目开发需要在框架的基础上进行!因为框架已经实现了一些功能,这样就可以提高开发效率! Struts2 = struts1  +  xwork (struts是基于MV ...

  2. ​ 用一个开发案例详解Oracle临时表

    ​ 用一个开发案例详解Oracle临时表 2016-11-14 bisal ITPUB  一.开发需求  最近有一个开发需求,大致需要先使用主表,或主表和几张子表关联查询出ID(主键)及一些主表字段 ...

  3. EJB3 阶段总结+一个EJB3案例 (1)

    经过一段时时间的学习,对EJB3的相关知识和jboss8的配置有了大概的了解. 网上对EJB的评论很多,基本都是负面的,都表示EJB太过于沉重,不容易维护.但通过这段时间的学习,私下认为,EJB3在某 ...

  4. SAP C/4HANA与人工智能和增强现实(AR)技术结合的又一个创新案例

    今天这篇迟到的文章,来自我的同事Aviva. 去年SAP C/4HANA发布之后,SAP的从业者们可能或多或少都读过一些来自SAP官方渠道,比如微信公众号"SAP天天事"发布的一些 ...

  5. Python:通过一个小案例深入理解IO多路复用

    通过一个小案例深入理解IO多路复用 假如我们现在有这样一个普通的需求,写一个简单的爬虫来爬取校花网的主页 import requests import time start = time.time() ...

  6. Lucene3.6.2包介绍,第一个Lucene案例介绍,查看索引信息的工具lukeall介绍,Luke查看的索引库内容,索引查找过程

    2.Lucene3.6.2包介绍,第一个Lucene案例介绍,查看索引信息的工具lukeall介绍,Luke查看的索引库内容,索引查找过程 2014-12-07 23:39 2623人阅读 评论(0) ...

  7. java线程基础巩固---分析Thread的join方法详细介绍,结合一个典型案例

    关于Thread中的join方法貌似在实际多线程编程当中没怎么用过,在当初学j2se的时候倒时去学习过它的用法,不过现在早已经忘得差不多啦,所以对它再复习复习下. 首先先观察下JDK对它的介绍: 其实 ...

  8. 编程中易犯错误汇总:一个综合案例.md

    # 11编程中易犯错误汇总:一个综合案例 在上一篇文章中,我们学习了如何区分好的代码与坏的代码,如何写好代码.所谓光说不练假把式,在这篇文章中,我们就做一件事——一起来写代码.首先,我会先列出问题,然 ...

  9. 零基础学习java------35---------删除一个商品案例,删除多个商品,编辑(修改商品信息),校验用户名是否已经注册(ajax)

    一. 删除一个商品案例 将要操作的表格 思路图  前端代码 <%@ page language="java" contentType="text/html; cha ...

随机推荐

  1. 每天一个linux命令(28)--gzip命令

    减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间.gzip 是在Linux 系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用.gzip 不仅 ...

  2. redhat linux enterprise 5 输入ifconfig无效的解决方法

    redhat linux enterprise 5 输入ifconfig无效的解决方法   在安装完成linux后,进入终端,输入命令行ifconfig,会提示bash: ifconfig: comm ...

  3. 队列工厂之(MSMQ)

    最近vs2017神器正式版发布让人很是激动,vs2017支持了很多语言的开发,从前端-后端-底层的支持,堪称是工具中的神器:netcore我喜爱的架构之一也得到了大力的宣传,应群友的邀请将在队列工厂( ...

  4. 深入理解 JavaScript 异步系列(4)—— Generator

    第一部分,ES6 中的 Generator 原文地址 http://www.cnblogs.com/wangfupeng1988/p/6532713.html 未经作者允许不得转载~ 在 ES6 出现 ...

  5. Python开发【第十八篇】Web框架之Django【基础篇】

    一.简介 Python下有许多款不同的 Web 框架,Django 是重量级选手中最有代表性的一位,许多成功的网站和APP都基于 Django. Django 是一个开放源代码的Web应用框架,由 P ...

  6. 算法模板——计算几何2(二维凸包——Andrew算法)

    实现功能:求出二维平面内一对散点的凸包(详见Codevs 1298) 很神奇的算法——先将各个点按坐标排序,然后像我们所知的那样一路左转,求出半边的凸包,然后反过来求另一半的凸包 我以前正是因为总抱着 ...

  7. MySQL基准测试(benchmark)

    基准测试是唯一方便有效的.可以学习系统在给定的工作负载下会发生什么的方法.基准测试可以观察系统在不同压力下的行为,评估系统的容量,掌握哪些是重要的变化,或者观察系统如何处理不同的数据. 验证基于系统的 ...

  8. 不可重入定时器Newlife.TimerX

    在.net常用的定时器类有下面三种,使用定时器时需要设定参数,如间断时间.定时器计溢出后的回调函数.延时.开始等,定时器的的主要方法有开始.终止等,不同的定时器实现上述的方法会有一些差异,本文会针对具 ...

  9. Python中的内置函数__init__()的理解

    有点意思,本来我是学习java的.总所周知,java也有构造函数,而python在面向对象的概念中,也有构造函数.它就是 __init__(self) 方法. 其实类似于__init__()这种方法, ...

  10. java学习笔记 --- 面向对象3

    一.创建对象是做了些什么事情? 图解: 二.static关键字 (1)静态的意思.可以修饰成员变量和成员方法. (2)静态的特点: 1.静态是随着类的加载就加载了.也是随着类的消失而消失了. 2.静态 ...