用SignalR实现的共享画板例子
使用HTML5的canvas画布功能,在页面进行绘画,然后通过SignalR将画布的每个点的颜色提交到服务端,服务端同时将这些画布的信息推送到其他客户端,实现共享同一个画板的功能
类似下图,在某一个浏览器进行绘画,其他浏览器同步显示内容,并且页面刷新或者首次加载还能显示之前的绘画内容(站点不重启的情况下)

实现过程
一、服务端
服务端的代码主要功能是接收客户端发送过来的绘画坐标点和坐标点的颜色,同时将新的坐标点信息推送给客户端,最后服务端还会保存这些绘画坐标点信息到内存中,这样客户端刷新或者首次进入就能看到之前的绘画信息。
step1:
创建一个Empty类型的ASP.NET 4.5的站点

step2:
引入SignalR的nuget包,将自动引入相关的关联包
Install-Package Microsoft.AspNet.SignalR
step3:
新建一个SignalR Hub Class
实现代码如下:
public class DrawingBoard : Hub
{
private const int BoardWidth = ;
private const int BoardHeight = ;
private static int[,] _pointBuffer = GetEmptyPointBuffer(); public Task DrawPoint(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);
_pointBuffer[x, y] = color;
return Clients.Others.drawPoint(x, y, Clients.Caller.color);
} public Task Clear()
{
_pointBuffer = GetEmptyPointBuffer();
return Clients.Others.clear();
} public override Task OnConnected()
{
return Clients.Caller.update(_pointBuffer);
} private static int[,] GetEmptyPointBuffer()
{
var buffer = new int[BoardWidth, BoardWidth];
return buffer;
}
}
step4:
新建一个startup类
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
Startup
到此完成服务端的功能实现
二、客户端
step1:
客户端的html页面只需要定义一个canvas元素和一个清除画布的按钮
<!DOCTYPE html>
<html>
<head>
<title>在线画板</title>
<meta charset="utf-8" />
<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>
<script src="/Scripts/jquery-1.6.4.min.js"></script>
<script src="/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="/signalr/js"></script>
<script src="/Scripts/drawingboard.js"></script>
</body>
</html>
Html
step2:
在scripts目录创建drawingboard.js文件,实现主要的画布操作和SingalR事件绑定。
主要是绑定了canvas的mousemove事件,然后再mousemove事件中实现绘画,同时将绘画的信息发送服务器,客户端同时接收服务端推送的绘画信息,实时提现在本地的画布中。
客户端连接成功之后,会获得从服务端推送的历史绘画信息,实现记载之前画布的效果
$(function () {
// 画布定义开始
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] + "</option>");
}
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 客户端代码
var hub = $.connection.drawingBoard;
hub.state.color = colorElement.val();
var connected = false;
colorElement.change(function () {
hub.state.color = $(this).val();
});
canvas.mousemove(function (e) {
if (buttonPressed && connected) {
hub.server.drawPoint(Math.round(e.offsetX), Math.round(e.offsetY));
}
});
$("#clear").click(function () {
if (connected) {
hub.server.clear();
}
});
// 定义客户端方法
hub.client.clear = function () {
clearPoints();
};
hub.client.drawPoint = function (x, y, color) {
setPoint(x, y, color);
};
hub.client.update = function (points) {
if (!points) return;
var width = canvas.width();
var height = canvas.height();
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
var color = points[x][y];
if (color > 0) {
setPoint(x, y, color);
}
}
}
};
$.connection.hub.start().done(function () {
connected = true;
});
})
drawingBoard
完整代码下载
用SignalR实现的共享画板例子的更多相关文章
- [置顶]
MVC中使用signalR入门教程
一.前言:每次写总要说一点最近的感想 进入工作快半年了,昨天是最郁闷的一天,我怀疑我是不是得了"星期一综合征",每个星期一很没有状态.全身都有点酸痛,这个可能一个星期只有周末才打一 ...
- OpenMP共享内存并行编程详解
实验平台:win7, VS2010 1. 介绍 平行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有 ...
- http与websocket(基于SignalR)两种协议下的跨域基于ASP.NET MVC--竹子整理
这段时间,项目涉及到移动端,这就不可避免的涉及到了跨域的问题.这是本人第一次接触跨域,有些地方的配置是有点麻烦,导致一开始的不顺. 至于websocket具体是什么意义,用途如何:请百度. 简单说就是 ...
- SAP内存/ABAP内存/共享内存区别
(1).读取和使用方法不同SAP内存使用SET/GET parameters方法:SET PARAMETER ID 'MAT' field p_matnr.GET PARAMETER ID 'MAT' ...
- 【转】七个例子帮你更好地理解 CPU 缓存
我的大多数读者都知道缓存是一种快速.小型.存储最近已访问的内存的地方.这个描述相当准确,但是深入处理器缓存如何工作的"枯燥"细节,会对尝试理解程序性能有很大帮助. 在这篇博文中,我 ...
- 读书笔记-----Java并发编程实战(二)对象的共享
public class NoVisibility{ private static boolean ready; private static int number; private static c ...
- 转:Spring-session & redis 子域名共享session
Spring-session & redis 子域名共享session 例子: a.example.com b.example.com spring 版本 4.2.6.RELEASE Spri ...
- .net core 使用SignalR实现实时通信
这几天在研究SignalR,网上大部分的例子都是聊天室,我的需求是把服务端的信息发送给前端展示.并且需要实现单个用户推送. 用户登录我用的是ClaimsIdentity,这里就不多解释,如果不是很了解 ...
- pipeline 共享库
目录 一.简介 二.共享库扩展 共享库使用 共享库结构 pipeline模板 一些小问题 三.共享库例子 使用公共变量 使用共享库的src方法 使用共享库的vars方法 四.插件实现pipeline ...
随机推荐
- CAS学习笔记(二)—— cas server端的login-webflow详细流程
一.配置文件介绍 关于spring的配置信息只需放入WEB-INF/spring-configuration目录即可,cas启动时会自动加载.这个目录下的spring配置文件几乎不需要改动. 在web ...
- C#数组的声明
C#一维数组的声明方式 int[] myArray; string[] myStrArr; 但是在访问数组之前必须初始化. C#数组的初始化方式有两种,第一种是在声明数组的时候为数组的元素赋初值: i ...
- JavaSE基础第四篇
1.参数传递 2,方法的重载 方法的参数的个数.类型.顺序 跟修饰符.返回值无关 3.构造方法: return 表示当前方法执行结束,后面不能写任何语句 4工程导入 单个.java文件粘贴 ...
- Mac下好用的编辑器VIM GUI版本 VimR 推荐
vim号称是编辑器之神,轮其功能和扩展性的确少有编辑器能比,但是大多数编辑器都有的文件浏览功能它确没有,虽然有些插件可以实现,但用起来都不是很方便,偶然发现了一个GUI版本的VIM,与普通的GUI版本 ...
- mysql 查询行号
SELECT @rowno:=@rowno+1 as rowno,r.* from t_zg_loanee_apply r,(select @rowno:=0) t;
- Bug修正
名称:nice! 项目名称:约跑app 组长:李权 成员:韩媛媛 刘芳芳 宫丽君 于淼 Bug修正: 1.我看到的现象:退出当前的账号后,按返回键可以再次进入登录界面. 期待的现象:能够安全登陆和退出 ...
- Window Azure ServiceBus Messaging消息队列技术系列2-编程SDK入门
各位,上一篇基本概念和架构中,我们介绍了Window Azure ServiceBus的消息队列技术的概览.接下来,我们进入编程模式和详细功能介绍模式,一点一点把ServiceBus技术研究出来. 本 ...
- sqlserver查询数据的所有表名和行数
//查询所有表明 select name from sysobjects where xtype='u' select * from sys.tables //查询数据库中所有的表名及行数 SELEC ...
- webpack模块依赖管理介绍
http://webpack.github.io/docs/ webpack is a module bundler. 是一个模块管理器 webpack可以管理模块的依赖关系,并产生可以替代这些模块的 ...
- Eclipse快捷键
http://www.blogjava.net/action/articles/17339.html http://blog.csdn.net/keenweiwei/article/details/3 ...